@sentry/node 9.13.0 → 9.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/index.js +5 -2
- package/build/cjs/index.js.map +1 -1
- package/build/cjs/integrations/anr/index.js +1 -1
- package/build/cjs/integrations/anr/index.js.map +1 -1
- package/build/cjs/integrations/context.js.map +1 -1
- package/build/cjs/integrations/contextlines.js.map +1 -1
- package/build/cjs/integrations/fs.js.map +1 -1
- package/build/cjs/integrations/http/SentryHttpInstrumentation.js +36 -37
- package/build/cjs/integrations/http/SentryHttpInstrumentation.js.map +1 -1
- package/build/cjs/integrations/http/SentryHttpInstrumentationBeforeOtel.js.map +1 -1
- package/build/cjs/integrations/http/vendor/getRequestInfo.js.map +1 -1
- package/build/cjs/integrations/local-variables/local-variables-async.js +1 -1
- package/build/cjs/integrations/local-variables/local-variables-async.js.map +1 -1
- package/build/cjs/integrations/local-variables/local-variables-sync.js.map +1 -1
- package/build/cjs/integrations/node-fetch/SentryNodeFetchInstrumentation.js.map +1 -1
- package/build/cjs/integrations/node-fetch/index.js.map +1 -1
- package/build/cjs/integrations/tracing/amqplib.js.map +1 -1
- package/build/cjs/integrations/tracing/connect.js.map +1 -1
- package/build/cjs/integrations/tracing/dataloader.js.map +1 -1
- package/build/cjs/integrations/tracing/express-v5/instrumentation.js.map +1 -1
- package/build/cjs/integrations/tracing/express.js.map +1 -1
- package/build/cjs/integrations/tracing/fastify.js.map +1 -1
- package/build/cjs/integrations/tracing/genericPool.js.map +1 -1
- package/build/cjs/integrations/tracing/graphql.js.map +1 -1
- package/build/cjs/integrations/tracing/hapi/index.js.map +1 -1
- package/build/cjs/integrations/tracing/index.js.map +1 -1
- package/build/cjs/integrations/tracing/knex.js.map +1 -1
- package/build/cjs/integrations/tracing/koa.js.map +1 -1
- package/build/cjs/integrations/tracing/lrumemoizer.js.map +1 -1
- package/build/cjs/integrations/tracing/mongo.js.map +1 -1
- package/build/cjs/integrations/tracing/mongoose.js.map +1 -1
- package/build/cjs/integrations/tracing/mysql.js.map +1 -1
- package/build/cjs/integrations/tracing/mysql2.js.map +1 -1
- package/build/cjs/integrations/tracing/postgres.js.map +1 -1
- package/build/cjs/integrations/tracing/prisma.js.map +1 -1
- package/build/cjs/integrations/tracing/redis.js.map +1 -1
- package/build/cjs/integrations/tracing/tedious.js.map +1 -1
- package/build/cjs/integrations/tracing/vercelai/index.js +0 -2
- package/build/cjs/integrations/tracing/vercelai/index.js.map +1 -1
- package/build/cjs/integrations/tracing/vercelai/instrumentation.js +20 -7
- package/build/cjs/integrations/tracing/vercelai/instrumentation.js.map +1 -1
- package/build/cjs/logs/capture.js.map +1 -1
- package/build/cjs/logs/exports.js.map +1 -1
- package/build/cjs/proxy/index.js.map +1 -1
- package/build/cjs/sdk/api.js.map +1 -1
- package/build/cjs/sdk/client.js.map +1 -1
- package/build/cjs/sdk/index.js.map +1 -1
- package/build/cjs/sdk/initOtel.js +2 -2
- package/build/cjs/sdk/initOtel.js.map +1 -1
- package/build/cjs/utils/addOriginToSpan.js.map +1 -1
- package/build/esm/index.js +3 -3
- package/build/esm/integrations/anr/index.js +1 -1
- package/build/esm/integrations/anr/index.js.map +1 -1
- package/build/esm/integrations/anr/worker-script.js +2 -2
- package/build/esm/integrations/context.js.map +1 -1
- package/build/esm/integrations/contextlines.js.map +1 -1
- package/build/esm/integrations/fs.js.map +1 -1
- package/build/esm/integrations/http/SentryHttpInstrumentation.js +36 -37
- package/build/esm/integrations/http/SentryHttpInstrumentation.js.map +1 -1
- package/build/esm/integrations/http/SentryHttpInstrumentationBeforeOtel.js.map +1 -1
- package/build/esm/integrations/http/vendor/getRequestInfo.js.map +1 -1
- package/build/esm/integrations/local-variables/local-variables-async.js +1 -1
- package/build/esm/integrations/local-variables/local-variables-async.js.map +1 -1
- package/build/esm/integrations/local-variables/local-variables-sync.js.map +1 -1
- package/build/esm/integrations/local-variables/worker-script.js +2 -2
- package/build/esm/integrations/node-fetch/SentryNodeFetchInstrumentation.js.map +1 -1
- package/build/esm/integrations/node-fetch/index.js.map +1 -1
- package/build/esm/integrations/tracing/amqplib.js.map +1 -1
- package/build/esm/integrations/tracing/connect.js.map +1 -1
- package/build/esm/integrations/tracing/dataloader.js.map +1 -1
- package/build/esm/integrations/tracing/express-v5/instrumentation.js.map +1 -1
- package/build/esm/integrations/tracing/express.js.map +1 -1
- package/build/esm/integrations/tracing/fastify.js.map +1 -1
- package/build/esm/integrations/tracing/genericPool.js.map +1 -1
- package/build/esm/integrations/tracing/graphql.js.map +1 -1
- package/build/esm/integrations/tracing/hapi/index.js.map +1 -1
- package/build/esm/integrations/tracing/index.js.map +1 -1
- package/build/esm/integrations/tracing/knex.js.map +1 -1
- package/build/esm/integrations/tracing/koa.js.map +1 -1
- package/build/esm/integrations/tracing/lrumemoizer.js.map +1 -1
- package/build/esm/integrations/tracing/mongo.js.map +1 -1
- package/build/esm/integrations/tracing/mongoose.js.map +1 -1
- package/build/esm/integrations/tracing/mysql.js.map +1 -1
- package/build/esm/integrations/tracing/mysql2.js.map +1 -1
- package/build/esm/integrations/tracing/postgres.js.map +1 -1
- package/build/esm/integrations/tracing/prisma.js.map +1 -1
- package/build/esm/integrations/tracing/redis.js.map +1 -1
- package/build/esm/integrations/tracing/tedious.js.map +1 -1
- package/build/esm/integrations/tracing/vercelai/index.js +0 -2
- package/build/esm/integrations/tracing/vercelai/index.js.map +1 -1
- package/build/esm/integrations/tracing/vercelai/instrumentation.js +20 -7
- package/build/esm/integrations/tracing/vercelai/instrumentation.js.map +1 -1
- package/build/esm/logs/capture.js.map +1 -1
- package/build/esm/logs/exports.js.map +1 -1
- package/build/esm/package.json +1 -1
- package/build/esm/proxy/index.js.map +1 -1
- package/build/esm/sdk/api.js.map +1 -1
- package/build/esm/sdk/client.js.map +1 -1
- package/build/esm/sdk/index.js.map +1 -1
- package/build/esm/sdk/initOtel.js +2 -2
- package/build/esm/sdk/initOtel.js.map +1 -1
- package/build/esm/utils/addOriginToSpan.js.map +1 -1
- package/build/types/index.d.ts +2 -2
- package/build/types/index.d.ts.map +1 -1
- package/build/types/integrations/context.d.ts +1 -1
- package/build/types/integrations/context.d.ts.map +1 -1
- package/build/types/integrations/http/SentryHttpInstrumentation.d.ts +2 -2
- package/build/types/integrations/http/SentryHttpInstrumentation.d.ts.map +1 -1
- package/build/types/integrations/http/SentryHttpInstrumentationBeforeOtel.d.ts.map +1 -1
- package/build/types/integrations/http/vendor/getRequestInfo.d.ts +1 -1
- package/build/types/integrations/http/vendor/getRequestInfo.d.ts.map +1 -1
- package/build/types/integrations/node-fetch/SentryNodeFetchInstrumentation.d.ts.map +1 -1
- package/build/types/integrations/tracing/amqplib.d.ts.map +1 -1
- package/build/types/integrations/tracing/graphql.d.ts.map +1 -1
- package/build/types/integrations/tracing/index.d.ts.map +1 -1
- package/build/types/integrations/tracing/lrumemoizer.d.ts.map +1 -1
- package/build/types/integrations/tracing/mongo.d.ts.map +1 -1
- package/build/types/integrations/tracing/mongoose.d.ts.map +1 -1
- package/build/types/integrations/tracing/mysql2.d.ts.map +1 -1
- package/build/types/integrations/tracing/postgres.d.ts.map +1 -1
- package/build/types/integrations/tracing/vercelai/instrumentation.d.ts +1 -1
- package/build/types/integrations/tracing/vercelai/instrumentation.d.ts.map +1 -1
- package/build/types/logs/capture.d.ts +1 -1
- package/build/types/logs/capture.d.ts.map +1 -1
- package/build/types/logs/exports.d.ts.map +1 -1
- package/build/types/proxy/index.d.ts +1 -1
- package/build/types/proxy/index.d.ts.map +1 -1
- package/build/types/sdk/client.d.ts.map +1 -1
- package/build/types/sdk/initOtel.d.ts.map +1 -1
- package/build/types/types.d.ts.map +1 -1
- package/build/types/utils/addOriginToSpan.d.ts.map +1 -1
- package/build/types/utils/prepareEvent.d.ts.map +1 -1
- package/build/types-ts3.8/index.d.ts +2 -2
- package/build/types-ts3.8/integrations/context.d.ts +1 -1
- package/build/types-ts3.8/integrations/http/SentryHttpInstrumentation.d.ts +2 -2
- package/build/types-ts3.8/integrations/http/vendor/getRequestInfo.d.ts +1 -1
- package/build/types-ts3.8/integrations/tracing/vercelai/instrumentation.d.ts +1 -1
- package/build/types-ts3.8/logs/capture.d.ts +1 -1
- package/build/types-ts3.8/proxy/index.d.ts +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/proxy/index.ts"],"sourcesContent":["/**\n * This code was originally forked from https://github.com/TooTallNate/proxy-agents/tree/b133295fd16f6475578b6b15bd9b4e33ecb0d0b7\n * With the following LICENSE:\n *\n * (The MIT License)\n *\n * Copyright (c) 2013 Nathan Rajlich <nathan@tootallnate.net>*\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * 'Software'), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:*\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.*\n *\n * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n/* eslint-disable @typescript-eslint/explicit-member-accessibility */\n/* eslint-disable @typescript-eslint/no-unused-vars */\nimport type * as http from 'node:http';\nimport type { OutgoingHttpHeaders } from 'node:http';\nimport * as net from 'node:net';\nimport * as tls from 'node:tls';\nimport { logger } from '@sentry/core';\nimport { Agent } from './base';\nimport type { AgentConnectOpts } from './base';\nimport { parseProxyResponse } from './parse-proxy-response';\n\nfunction debug(...args: unknown[]): void {\n logger.log('[https-proxy-agent]', ...args);\n}\n\ntype Protocol<T> = T extends `${infer Protocol}:${infer _}` ? Protocol : never;\n\ntype ConnectOptsMap = {\n http: Omit<net.TcpNetConnectOpts, 'host' | 'port'>;\n https: Omit<tls.ConnectionOptions, 'host' | 'port'>;\n};\n\ntype ConnectOpts<T> = {\n [P in keyof ConnectOptsMap]: Protocol<T> extends P ? ConnectOptsMap[P] : never;\n}[keyof ConnectOptsMap];\n\nexport type HttpsProxyAgentOptions<T> = ConnectOpts<T> &\n http.AgentOptions & {\n headers?: OutgoingHttpHeaders | (() => OutgoingHttpHeaders);\n };\n\n/**\n * The `HttpsProxyAgent` implements an HTTP Agent subclass that connects to\n * the specified \"HTTP(s) proxy server\" in order to proxy HTTPS requests.\n *\n * Outgoing HTTP requests are first tunneled through the proxy server using the\n * `CONNECT` HTTP request method to establish a connection to the proxy server,\n * and then the proxy server connects to the destination target and issues the\n * HTTP request from the proxy server.\n *\n * `https:` requests have their socket connection upgraded to TLS once\n * the connection to the proxy server has been established.\n */\nexport class HttpsProxyAgent<Uri extends string> extends Agent {\n static protocols = ['http', 'https'] as const;\n\n readonly proxy: URL;\n proxyHeaders: OutgoingHttpHeaders | (() => OutgoingHttpHeaders);\n connectOpts: net.TcpNetConnectOpts & tls.ConnectionOptions;\n\n constructor(proxy: Uri | URL, opts?: HttpsProxyAgentOptions<Uri>) {\n super(opts);\n this.options = {};\n this.proxy = typeof proxy === 'string' ? new URL(proxy) : proxy;\n this.proxyHeaders = opts?.headers ?? {};\n debug('Creating new HttpsProxyAgent instance: %o', this.proxy.href);\n\n // Trim off the brackets from IPv6 addresses\n const host = (this.proxy.hostname || this.proxy.host).replace(/^\\[|\\]$/g, '');\n const port = this.proxy.port ? parseInt(this.proxy.port, 10) : this.proxy.protocol === 'https:' ? 443 : 80;\n this.connectOpts = {\n // Attempt to negotiate http/1.1 for proxy servers that support http/2\n ALPNProtocols: ['http/1.1'],\n ...(opts ? omit(opts, 'headers') : null),\n host,\n port,\n };\n }\n\n /**\n * Called when the node-core HTTP client library is creating a\n * new HTTP request.\n */\n async connect(req: http.ClientRequest, opts: AgentConnectOpts): Promise<net.Socket> {\n const { proxy } = this;\n\n if (!opts.host) {\n throw new TypeError('No \"host\" provided');\n }\n\n // Create a socket connection to the proxy server.\n let socket: net.Socket;\n if (proxy.protocol === 'https:') {\n debug('Creating `tls.Socket`: %o', this.connectOpts);\n const servername = this.connectOpts.servername || this.connectOpts.host;\n socket = tls.connect({\n ...this.connectOpts,\n servername: servername && net.isIP(servername) ? undefined : servername,\n });\n } else {\n debug('Creating `net.Socket`: %o', this.connectOpts);\n socket = net.connect(this.connectOpts);\n }\n\n const headers: OutgoingHttpHeaders =\n typeof this.proxyHeaders === 'function' ? this.proxyHeaders() : { ...this.proxyHeaders };\n const host = net.isIPv6(opts.host) ? `[${opts.host}]` : opts.host;\n let payload = `CONNECT ${host}:${opts.port} HTTP/1.1\\r\\n`;\n\n // Inject the `Proxy-Authorization` header if necessary.\n if (proxy.username || proxy.password) {\n const auth = `${decodeURIComponent(proxy.username)}:${decodeURIComponent(proxy.password)}`;\n headers['Proxy-Authorization'] = `Basic ${Buffer.from(auth).toString('base64')}`;\n }\n\n headers.Host = `${host}:${opts.port}`;\n\n if (!headers['Proxy-Connection']) {\n headers['Proxy-Connection'] = this.keepAlive ? 'Keep-Alive' : 'close';\n }\n for (const name of Object.keys(headers)) {\n payload += `${name}: ${headers[name]}\\r\\n`;\n }\n\n const proxyResponsePromise = parseProxyResponse(socket);\n\n socket.write(`${payload}\\r\\n`);\n\n const { connect, buffered } = await proxyResponsePromise;\n req.emit('proxyConnect', connect);\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore Not EventEmitter in Node types\n this.emit('proxyConnect', connect, req);\n\n if (connect.statusCode === 200) {\n req.once('socket', resume);\n\n if (opts.secureEndpoint) {\n // The proxy is connecting to a TLS server, so upgrade\n // this socket connection to a TLS connection.\n debug('Upgrading socket connection to TLS');\n const servername = opts.servername || opts.host;\n return tls.connect({\n ...omit(opts, 'host', 'path', 'port'),\n socket,\n servername: net.isIP(servername) ? undefined : servername,\n });\n }\n\n return socket;\n }\n\n // Some other status code that's not 200... need to re-play the HTTP\n // header \"data\" events onto the socket once the HTTP machinery is\n // attached so that the node core `http` can parse and handle the\n // error status code.\n\n // Close the original socket, and a new \"fake\" socket is returned\n // instead, so that the proxy doesn't get the HTTP request\n // written to it (which may contain `Authorization` headers or other\n // sensitive data).\n //\n // See: https://hackerone.com/reports/541502\n socket.destroy();\n\n const fakeSocket = new net.Socket({ writable: false });\n fakeSocket.readable = true;\n\n // Need to wait for the \"socket\" event to re-play the \"data\" events.\n req.once('socket', (s: net.Socket) => {\n debug('Replaying proxy buffer for failed request');\n // Replay the \"buffered\" Buffer onto the fake `socket`, since at\n // this point the HTTP module machinery has been hooked up for\n // the user.\n s.push(buffered);\n s.push(null);\n });\n\n return fakeSocket;\n }\n}\n\nfunction resume(socket: net.Socket | tls.TLSSocket): void {\n socket.resume();\n}\n\nfunction omit<T extends object, K extends [...(keyof T)[]]>(\n obj: T,\n ...keys: K\n): {\n [K2 in Exclude<keyof T, K[number]>]: T[K2];\n} {\n const ret = {} as {\n [K in keyof typeof obj]: (typeof obj)[K];\n };\n let key: keyof typeof obj;\n for (key in obj) {\n if (!keys.includes(key)) {\n ret[key] = obj[key];\n }\n }\n return ret;\n}\n"],"names":["logger","Agent","parseProxyResponse"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/proxy/index.ts"],"sourcesContent":["/**\n * This code was originally forked from https://github.com/TooTallNate/proxy-agents/tree/b133295fd16f6475578b6b15bd9b4e33ecb0d0b7\n * With the following LICENSE:\n *\n * (The MIT License)\n *\n * Copyright (c) 2013 Nathan Rajlich <nathan@tootallnate.net>*\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * 'Software'), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:*\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.*\n *\n * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n/* eslint-disable @typescript-eslint/explicit-member-accessibility */\n/* eslint-disable @typescript-eslint/no-unused-vars */\nimport type * as http from 'node:http';\nimport type { OutgoingHttpHeaders } from 'node:http';\nimport * as net from 'node:net';\nimport * as tls from 'node:tls';\nimport { logger } from '@sentry/core';\nimport type { AgentConnectOpts } from './base';\nimport { Agent } from './base';\nimport { parseProxyResponse } from './parse-proxy-response';\n\nfunction debug(...args: unknown[]): void {\n logger.log('[https-proxy-agent]', ...args);\n}\n\ntype Protocol<T> = T extends `${infer Protocol}:${infer _}` ? Protocol : never;\n\ntype ConnectOptsMap = {\n http: Omit<net.TcpNetConnectOpts, 'host' | 'port'>;\n https: Omit<tls.ConnectionOptions, 'host' | 'port'>;\n};\n\ntype ConnectOpts<T> = {\n [P in keyof ConnectOptsMap]: Protocol<T> extends P ? ConnectOptsMap[P] : never;\n}[keyof ConnectOptsMap];\n\nexport type HttpsProxyAgentOptions<T> = ConnectOpts<T> &\n http.AgentOptions & {\n headers?: OutgoingHttpHeaders | (() => OutgoingHttpHeaders);\n };\n\n/**\n * The `HttpsProxyAgent` implements an HTTP Agent subclass that connects to\n * the specified \"HTTP(s) proxy server\" in order to proxy HTTPS requests.\n *\n * Outgoing HTTP requests are first tunneled through the proxy server using the\n * `CONNECT` HTTP request method to establish a connection to the proxy server,\n * and then the proxy server connects to the destination target and issues the\n * HTTP request from the proxy server.\n *\n * `https:` requests have their socket connection upgraded to TLS once\n * the connection to the proxy server has been established.\n */\nexport class HttpsProxyAgent<Uri extends string> extends Agent {\n static protocols = ['http', 'https'] as const;\n\n readonly proxy: URL;\n proxyHeaders: OutgoingHttpHeaders | (() => OutgoingHttpHeaders);\n connectOpts: net.TcpNetConnectOpts & tls.ConnectionOptions;\n\n constructor(proxy: Uri | URL, opts?: HttpsProxyAgentOptions<Uri>) {\n super(opts);\n this.options = {};\n this.proxy = typeof proxy === 'string' ? new URL(proxy) : proxy;\n this.proxyHeaders = opts?.headers ?? {};\n debug('Creating new HttpsProxyAgent instance: %o', this.proxy.href);\n\n // Trim off the brackets from IPv6 addresses\n const host = (this.proxy.hostname || this.proxy.host).replace(/^\\[|\\]$/g, '');\n const port = this.proxy.port ? parseInt(this.proxy.port, 10) : this.proxy.protocol === 'https:' ? 443 : 80;\n this.connectOpts = {\n // Attempt to negotiate http/1.1 for proxy servers that support http/2\n ALPNProtocols: ['http/1.1'],\n ...(opts ? omit(opts, 'headers') : null),\n host,\n port,\n };\n }\n\n /**\n * Called when the node-core HTTP client library is creating a\n * new HTTP request.\n */\n async connect(req: http.ClientRequest, opts: AgentConnectOpts): Promise<net.Socket> {\n const { proxy } = this;\n\n if (!opts.host) {\n throw new TypeError('No \"host\" provided');\n }\n\n // Create a socket connection to the proxy server.\n let socket: net.Socket;\n if (proxy.protocol === 'https:') {\n debug('Creating `tls.Socket`: %o', this.connectOpts);\n const servername = this.connectOpts.servername || this.connectOpts.host;\n socket = tls.connect({\n ...this.connectOpts,\n servername: servername && net.isIP(servername) ? undefined : servername,\n });\n } else {\n debug('Creating `net.Socket`: %o', this.connectOpts);\n socket = net.connect(this.connectOpts);\n }\n\n const headers: OutgoingHttpHeaders =\n typeof this.proxyHeaders === 'function' ? this.proxyHeaders() : { ...this.proxyHeaders };\n const host = net.isIPv6(opts.host) ? `[${opts.host}]` : opts.host;\n let payload = `CONNECT ${host}:${opts.port} HTTP/1.1\\r\\n`;\n\n // Inject the `Proxy-Authorization` header if necessary.\n if (proxy.username || proxy.password) {\n const auth = `${decodeURIComponent(proxy.username)}:${decodeURIComponent(proxy.password)}`;\n headers['Proxy-Authorization'] = `Basic ${Buffer.from(auth).toString('base64')}`;\n }\n\n headers.Host = `${host}:${opts.port}`;\n\n if (!headers['Proxy-Connection']) {\n headers['Proxy-Connection'] = this.keepAlive ? 'Keep-Alive' : 'close';\n }\n for (const name of Object.keys(headers)) {\n payload += `${name}: ${headers[name]}\\r\\n`;\n }\n\n const proxyResponsePromise = parseProxyResponse(socket);\n\n socket.write(`${payload}\\r\\n`);\n\n const { connect, buffered } = await proxyResponsePromise;\n req.emit('proxyConnect', connect);\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore Not EventEmitter in Node types\n this.emit('proxyConnect', connect, req);\n\n if (connect.statusCode === 200) {\n req.once('socket', resume);\n\n if (opts.secureEndpoint) {\n // The proxy is connecting to a TLS server, so upgrade\n // this socket connection to a TLS connection.\n debug('Upgrading socket connection to TLS');\n const servername = opts.servername || opts.host;\n return tls.connect({\n ...omit(opts, 'host', 'path', 'port'),\n socket,\n servername: net.isIP(servername) ? undefined : servername,\n });\n }\n\n return socket;\n }\n\n // Some other status code that's not 200... need to re-play the HTTP\n // header \"data\" events onto the socket once the HTTP machinery is\n // attached so that the node core `http` can parse and handle the\n // error status code.\n\n // Close the original socket, and a new \"fake\" socket is returned\n // instead, so that the proxy doesn't get the HTTP request\n // written to it (which may contain `Authorization` headers or other\n // sensitive data).\n //\n // See: https://hackerone.com/reports/541502\n socket.destroy();\n\n const fakeSocket = new net.Socket({ writable: false });\n fakeSocket.readable = true;\n\n // Need to wait for the \"socket\" event to re-play the \"data\" events.\n req.once('socket', (s: net.Socket) => {\n debug('Replaying proxy buffer for failed request');\n // Replay the \"buffered\" Buffer onto the fake `socket`, since at\n // this point the HTTP module machinery has been hooked up for\n // the user.\n s.push(buffered);\n s.push(null);\n });\n\n return fakeSocket;\n }\n}\n\nfunction resume(socket: net.Socket | tls.TLSSocket): void {\n socket.resume();\n}\n\nfunction omit<T extends object, K extends [...(keyof T)[]]>(\n obj: T,\n ...keys: K\n): {\n [K2 in Exclude<keyof T, K[number]>]: T[K2];\n} {\n const ret = {} as {\n [K in keyof typeof obj]: (typeof obj)[K];\n };\n let key: keyof typeof obj;\n for (key in obj) {\n if (!keys.includes(key)) {\n ret[key] = obj[key];\n }\n }\n return ret;\n}\n"],"names":["logger","Agent","parseProxyResponse"],"mappings":"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"}
|
package/build/cjs/sdk/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sources":["../../../src/sdk/api.ts"],"sourcesContent":["// PUBLIC APIS\n\nimport type { StackParser } from '@sentry/core';\nimport {
|
|
1
|
+
{"version":3,"file":"api.js","sources":["../../../src/sdk/api.ts"],"sourcesContent":["// PUBLIC APIS\n\nimport type { StackParser } from '@sentry/core';\nimport { createStackParser, GLOBAL_OBJ, nodeStackLineParser } from '@sentry/core';\nimport { createGetModuleFromFilename } from '../utils/module';\n\n/**\n * Returns a release dynamically from environment variables.\n */\n// eslint-disable-next-line complexity\nexport function getSentryRelease(fallback?: string): string | undefined {\n // Always read first as Sentry takes this as precedence\n if (process.env.SENTRY_RELEASE) {\n return process.env.SENTRY_RELEASE;\n }\n\n // This supports the variable that sentry-webpack-plugin injects\n if (GLOBAL_OBJ.SENTRY_RELEASE?.id) {\n return GLOBAL_OBJ.SENTRY_RELEASE.id;\n }\n\n // This list is in approximate alpha order, separated into 3 categories:\n // 1. Git providers\n // 2. CI providers with specific environment variables (has the provider name in the variable name)\n // 3. CI providers with generic environment variables (checked for last to prevent possible false positives)\n\n const possibleReleaseNameOfGitProvider =\n // GitHub Actions - https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables\n process.env['GITHUB_SHA'] ||\n // GitLab CI - https://docs.gitlab.com/ee/ci/variables/predefined_variables.html\n process.env['CI_MERGE_REQUEST_SOURCE_BRANCH_SHA'] ||\n process.env['CI_BUILD_REF'] ||\n process.env['CI_COMMIT_SHA'] ||\n // Bitbucket - https://support.atlassian.com/bitbucket-cloud/docs/variables-and-secrets/\n process.env['BITBUCKET_COMMIT'];\n\n const possibleReleaseNameOfCiProvidersWithSpecificEnvVar =\n // AppVeyor - https://www.appveyor.com/docs/environment-variables/\n process.env['APPVEYOR_PULL_REQUEST_HEAD_COMMIT'] ||\n process.env['APPVEYOR_REPO_COMMIT'] ||\n // AWS CodeBuild - https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-env-vars.html\n process.env['CODEBUILD_RESOLVED_SOURCE_VERSION'] ||\n // AWS Amplify - https://docs.aws.amazon.com/amplify/latest/userguide/environment-variables.html\n process.env['AWS_COMMIT_ID'] ||\n // Azure Pipelines - https://docs.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml\n process.env['BUILD_SOURCEVERSION'] ||\n // Bitrise - https://devcenter.bitrise.io/builds/available-environment-variables/\n process.env['GIT_CLONE_COMMIT_HASH'] ||\n // Buddy CI - https://buddy.works/docs/pipelines/environment-variables#default-environment-variables\n process.env['BUDDY_EXECUTION_REVISION'] ||\n // Builtkite - https://buildkite.com/docs/pipelines/environment-variables\n process.env['BUILDKITE_COMMIT'] ||\n // CircleCI - https://circleci.com/docs/variables/\n process.env['CIRCLE_SHA1'] ||\n // Cirrus CI - https://cirrus-ci.org/guide/writing-tasks/#environment-variables\n process.env['CIRRUS_CHANGE_IN_REPO'] ||\n // Codefresh - https://codefresh.io/docs/docs/codefresh-yaml/variables/\n process.env['CF_REVISION'] ||\n // Codemagic - https://docs.codemagic.io/yaml-basic-configuration/environment-variables/\n process.env['CM_COMMIT'] ||\n // Cloudflare Pages - https://developers.cloudflare.com/pages/platform/build-configuration/#environment-variables\n process.env['CF_PAGES_COMMIT_SHA'] ||\n // Drone - https://docs.drone.io/pipeline/environment/reference/\n process.env['DRONE_COMMIT_SHA'] ||\n // Flightcontrol - https://www.flightcontrol.dev/docs/guides/flightcontrol/environment-variables#built-in-environment-variables\n process.env['FC_GIT_COMMIT_SHA'] ||\n // Heroku #1 https://devcenter.heroku.com/articles/heroku-ci\n process.env['HEROKU_TEST_RUN_COMMIT_VERSION'] ||\n // Heroku #2 https://docs.sentry.io/product/integrations/deployment/heroku/#configure-releases\n process.env['HEROKU_SLUG_COMMIT'] ||\n // Railway - https://docs.railway.app/reference/variables#git-variables\n process.env['RAILWAY_GIT_COMMIT_SHA'] ||\n // Render - https://render.com/docs/environment-variables\n process.env['RENDER_GIT_COMMIT'] ||\n // Semaphore CI - https://docs.semaphoreci.com/ci-cd-environment/environment-variables\n process.env['SEMAPHORE_GIT_SHA'] ||\n // TravisCI - https://docs.travis-ci.com/user/environment-variables/#default-environment-variables\n process.env['TRAVIS_PULL_REQUEST_SHA'] ||\n // Vercel - https://vercel.com/docs/v2/build-step#system-environment-variables\n process.env['VERCEL_GIT_COMMIT_SHA'] ||\n process.env['VERCEL_GITHUB_COMMIT_SHA'] ||\n process.env['VERCEL_GITLAB_COMMIT_SHA'] ||\n process.env['VERCEL_BITBUCKET_COMMIT_SHA'] ||\n // Zeit (now known as Vercel)\n process.env['ZEIT_GITHUB_COMMIT_SHA'] ||\n process.env['ZEIT_GITLAB_COMMIT_SHA'] ||\n process.env['ZEIT_BITBUCKET_COMMIT_SHA'];\n\n const possibleReleaseNameOfCiProvidersWithGenericEnvVar =\n // CloudBees CodeShip - https://docs.cloudbees.com/docs/cloudbees-codeship/latest/pro-builds-and-configuration/environment-variables\n process.env['CI_COMMIT_ID'] ||\n // Coolify - https://coolify.io/docs/knowledge-base/environment-variables\n process.env['SOURCE_COMMIT'] ||\n // Heroku #3 https://devcenter.heroku.com/changelog-items/630\n process.env['SOURCE_VERSION'] ||\n // Jenkins - https://plugins.jenkins.io/git/#environment-variables\n process.env['GIT_COMMIT'] ||\n // Netlify - https://docs.netlify.com/configure-builds/environment-variables/#build-metadata\n process.env['COMMIT_REF'] ||\n // TeamCity - https://www.jetbrains.com/help/teamcity/predefined-build-parameters.html\n process.env['BUILD_VCS_NUMBER'] ||\n // Woodpecker CI - https://woodpecker-ci.org/docs/usage/environment\n process.env['CI_COMMIT_SHA'];\n\n return (\n possibleReleaseNameOfGitProvider ||\n possibleReleaseNameOfCiProvidersWithSpecificEnvVar ||\n possibleReleaseNameOfCiProvidersWithGenericEnvVar ||\n fallback\n );\n}\n\n/** Node.js stack parser */\nexport const defaultStackParser: StackParser = createStackParser(nodeStackLineParser(createGetModuleFromFilename()));\n"],"names":["GLOBAL_OBJ","createStackParser","nodeStackLineParser","createGetModuleFromFilename"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sources":["../../../src/sdk/client.ts"],"sourcesContent":["import * as os from 'node:os';\nimport type { Tracer } from '@opentelemetry/api';\nimport { trace } from '@opentelemetry/api';\nimport { registerInstrumentations } from '@opentelemetry/instrumentation';\nimport type { BasicTracerProvider } from '@opentelemetry/sdk-trace-base';\nimport type { DynamicSamplingContext, Scope, ServerRuntimeClientOptions, TraceContext } from '@sentry/core';\nimport { _INTERNAL_flushLogsBuffer,
|
|
1
|
+
{"version":3,"file":"client.js","sources":["../../../src/sdk/client.ts"],"sourcesContent":["import * as os from 'node:os';\nimport type { Tracer } from '@opentelemetry/api';\nimport { trace } from '@opentelemetry/api';\nimport { registerInstrumentations } from '@opentelemetry/instrumentation';\nimport type { BasicTracerProvider } from '@opentelemetry/sdk-trace-base';\nimport type { DynamicSamplingContext, Scope, ServerRuntimeClientOptions, TraceContext } from '@sentry/core';\nimport { _INTERNAL_flushLogsBuffer, applySdkMetadata, logger, SDK_VERSION, ServerRuntimeClient } from '@sentry/core';\nimport { getTraceContextForScope } from '@sentry/opentelemetry';\nimport { isMainThread, threadId } from 'worker_threads';\nimport { DEBUG_BUILD } from '../debug-build';\nimport type { NodeClientOptions } from '../types';\n\nconst DEFAULT_CLIENT_REPORT_FLUSH_INTERVAL_MS = 60_000; // 60s was chosen arbitrarily\n\n/** A client for using Sentry with Node & OpenTelemetry. */\nexport class NodeClient extends ServerRuntimeClient<NodeClientOptions> {\n public traceProvider: BasicTracerProvider | undefined;\n private _tracer: Tracer | undefined;\n private _clientReportInterval: NodeJS.Timeout | undefined;\n private _clientReportOnExitFlushListener: (() => void) | undefined;\n private _logOnExitFlushListener: (() => void) | undefined;\n\n public constructor(options: NodeClientOptions) {\n const serverName = options.serverName || global.process.env.SENTRY_NAME || os.hostname();\n const clientOptions: ServerRuntimeClientOptions = {\n ...options,\n platform: 'node',\n runtime: { name: 'node', version: global.process.version },\n serverName,\n };\n\n if (options.openTelemetryInstrumentations) {\n registerInstrumentations({\n instrumentations: options.openTelemetryInstrumentations,\n });\n }\n\n applySdkMetadata(clientOptions, 'node');\n\n logger.log(\n `Initializing Sentry: process: ${process.pid}, thread: ${isMainThread ? 'main' : `worker-${threadId}`}.`,\n );\n\n super(clientOptions);\n\n if (this.getOptions()._experiments?.enableLogs) {\n this._logOnExitFlushListener = () => {\n _INTERNAL_flushLogsBuffer(this);\n };\n\n if (serverName) {\n this.on('beforeCaptureLog', log => {\n log.attributes = {\n ...log.attributes,\n 'server.address': serverName,\n };\n });\n }\n\n process.on('beforeExit', this._logOnExitFlushListener);\n }\n }\n\n /** Get the OTEL tracer. */\n public get tracer(): Tracer {\n if (this._tracer) {\n return this._tracer;\n }\n\n const name = '@sentry/node';\n const version = SDK_VERSION;\n const tracer = trace.getTracer(name, version);\n this._tracer = tracer;\n\n return tracer;\n }\n\n // Eslint ignore explanation: This is already documented in super.\n // eslint-disable-next-line jsdoc/require-jsdoc\n public async flush(timeout?: number): Promise<boolean> {\n const provider = this.traceProvider;\n const spanProcessor = provider?.activeSpanProcessor;\n\n if (spanProcessor) {\n await spanProcessor.forceFlush();\n }\n\n if (this.getOptions().sendClientReports) {\n this._flushOutcomes();\n }\n\n return super.flush(timeout);\n }\n\n // Eslint ignore explanation: This is already documented in super.\n // eslint-disable-next-line jsdoc/require-jsdoc\n public close(timeout?: number | undefined): PromiseLike<boolean> {\n if (this._clientReportInterval) {\n clearInterval(this._clientReportInterval);\n }\n\n if (this._clientReportOnExitFlushListener) {\n process.off('beforeExit', this._clientReportOnExitFlushListener);\n }\n\n if (this._logOnExitFlushListener) {\n process.off('beforeExit', this._logOnExitFlushListener);\n }\n\n return super.close(timeout);\n }\n\n /**\n * Will start tracking client reports for this client.\n *\n * NOTICE: This method will create an interval that is periodically called and attach a `process.on('beforeExit')`\n * hook. To clean up these resources, call `.close()` when you no longer intend to use the client. Not doing so will\n * result in a memory leak.\n */\n // The reason client reports need to be manually activated with this method instead of just enabling them in a\n // constructor, is that if users periodically and unboundedly create new clients, we will create more and more\n // intervals and beforeExit listeners, thus leaking memory. In these situations, users are required to call\n // `client.close()` in order to dispose of the acquired resources.\n // We assume that calling this method in Sentry.init() is a sensible default, because calling Sentry.init() over and\n // over again would also result in memory leaks.\n // Note: We have experimented with using `FinalizationRegisty` to clear the interval when the client is garbage\n // collected, but it did not work, because the cleanup function never got called.\n public startClientReportTracking(): void {\n const clientOptions = this.getOptions();\n if (clientOptions.sendClientReports) {\n this._clientReportOnExitFlushListener = () => {\n this._flushOutcomes();\n };\n\n this._clientReportInterval = setInterval(() => {\n DEBUG_BUILD && logger.log('Flushing client reports based on interval.');\n this._flushOutcomes();\n }, clientOptions.clientReportFlushInterval ?? DEFAULT_CLIENT_REPORT_FLUSH_INTERVAL_MS)\n // Unref is critical for not preventing the process from exiting because the interval is active.\n .unref();\n\n process.on('beforeExit', this._clientReportOnExitFlushListener);\n }\n }\n\n /** Custom implementation for OTEL, so we can handle scope-span linking. */\n protected _getTraceInfoFromScope(\n scope: Scope | undefined,\n ): [dynamicSamplingContext: Partial<DynamicSamplingContext> | undefined, traceContext: TraceContext | undefined] {\n if (!scope) {\n return [undefined, undefined];\n }\n\n return getTraceContextForScope(this, scope);\n }\n}\n"],"names":["ServerRuntimeClient","registerInstrumentations","applySdkMetadata","logger","isMainThread","threadId","_INTERNAL_flushLogsBuffer","SDK_VERSION","trace","DEBUG_BUILD","getTraceContextForScope"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/sdk/index.ts"],"sourcesContent":["import type { Integration, Options } from '@sentry/core';\nimport {\n consoleSandbox,\n functionToStringIntegration,\n getCurrentScope,\n getIntegrationsToSetup,\n hasSpansEnabled,\n inboundFiltersIntegration,\n linkedErrorsIntegration,\n logger,\n propagationContextFromHeaders,\n requestDataIntegration,\n stackParserFromStackParserOptions,\n consoleIntegration,\n} from '@sentry/core';\nimport {\n enhanceDscWithOpenTelemetryRootSpanName,\n openTelemetrySetupCheck,\n setOpenTelemetryContextAsyncContextStrategy,\n setupEventContextTrace,\n} from '@sentry/opentelemetry';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { childProcessIntegration } from '../integrations/childProcess';\nimport { nodeContextIntegration } from '../integrations/context';\nimport { contextLinesIntegration } from '../integrations/contextlines';\nimport { httpIntegration } from '../integrations/http';\nimport { localVariablesIntegration } from '../integrations/local-variables';\nimport { modulesIntegration } from '../integrations/modules';\nimport { nativeNodeFetchIntegration } from '../integrations/node-fetch';\nimport { onUncaughtExceptionIntegration } from '../integrations/onuncaughtexception';\nimport { onUnhandledRejectionIntegration } from '../integrations/onunhandledrejection';\nimport { processSessionIntegration } from '../integrations/processSession';\nimport { INTEGRATION_NAME as SPOTLIGHT_INTEGRATION_NAME, spotlightIntegration } from '../integrations/spotlight';\nimport { getAutoPerformanceIntegrations } from '../integrations/tracing';\nimport { makeNodeTransport } from '../transports';\nimport type { NodeClientOptions, NodeOptions } from '../types';\nimport { isCjs } from '../utils/commonjs';\nimport { envToBool } from '../utils/envToBool';\nimport { defaultStackParser, getSentryRelease } from './api';\nimport { NodeClient } from './client';\nimport { initOpenTelemetry, maybeInitializeEsmLoader } from './initOtel';\n\nfunction getCjsOnlyIntegrations(): Integration[] {\n return isCjs() ? [modulesIntegration()] : [];\n}\n\n/**\n * Get default integrations, excluding performance.\n */\nexport function getDefaultIntegrationsWithoutPerformance(): Integration[] {\n return [\n // Common\n // TODO(v10): Replace with `eventFiltersIntegration` once we remove the deprecated `inboundFiltersIntegration`\n // eslint-disable-next-line deprecation/deprecation\n inboundFiltersIntegration(),\n functionToStringIntegration(),\n linkedErrorsIntegration(),\n requestDataIntegration(),\n // Native Wrappers\n consoleIntegration(),\n httpIntegration(),\n nativeNodeFetchIntegration(),\n // Global Handlers\n onUncaughtExceptionIntegration(),\n onUnhandledRejectionIntegration(),\n // Event Info\n contextLinesIntegration(),\n localVariablesIntegration(),\n nodeContextIntegration(),\n childProcessIntegration(),\n processSessionIntegration(),\n ...getCjsOnlyIntegrations(),\n ];\n}\n\n/** Get the default integrations for the Node SDK. */\nexport function getDefaultIntegrations(options: Options): Integration[] {\n return [\n ...getDefaultIntegrationsWithoutPerformance(),\n // We only add performance integrations if tracing is enabled\n // Note that this means that without tracing enabled, e.g. `expressIntegration()` will not be added\n // This means that generally request isolation will work (because that is done by httpIntegration)\n // But `transactionName` will not be set automatically\n ...(hasSpansEnabled(options) ? getAutoPerformanceIntegrations() : []),\n ];\n}\n\n/**\n * Initialize Sentry for Node.\n */\nexport function init(options: NodeOptions | undefined = {}): NodeClient | undefined {\n return _init(options, getDefaultIntegrations);\n}\n\n/**\n * Initialize Sentry for Node, without any integrations added by default.\n */\nexport function initWithoutDefaultIntegrations(options: NodeOptions | undefined = {}): NodeClient {\n return _init(options, () => []);\n}\n\n/**\n * Initialize Sentry for Node, without performance instrumentation.\n */\nfunction _init(\n _options: NodeOptions | undefined = {},\n getDefaultIntegrationsImpl: (options: Options) => Integration[],\n): NodeClient {\n const options = getClientOptions(_options, getDefaultIntegrationsImpl);\n\n if (options.debug === true) {\n if (DEBUG_BUILD) {\n logger.enable();\n } else {\n // use `console.warn` rather than `logger.warn` since by non-debug bundles have all `logger.x` statements stripped\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn('[Sentry] Cannot initialize SDK with `debug` option using a non-debug bundle.');\n });\n }\n }\n\n if (!isCjs() && options.registerEsmLoaderHooks !== false) {\n maybeInitializeEsmLoader();\n }\n\n setOpenTelemetryContextAsyncContextStrategy();\n\n const scope = getCurrentScope();\n scope.update(options.initialScope);\n\n if (options.spotlight && !options.integrations.some(({ name }) => name === SPOTLIGHT_INTEGRATION_NAME)) {\n options.integrations.push(\n spotlightIntegration({\n sidecarUrl: typeof options.spotlight === 'string' ? options.spotlight : undefined,\n }),\n );\n }\n\n const client = new NodeClient(options);\n // The client is on the current scope, from where it generally is inherited\n getCurrentScope().setClient(client);\n\n client.init();\n\n logger.log(`Running in ${isCjs() ? 'CommonJS' : 'ESM'} mode.`);\n\n client.startClientReportTracking();\n\n updateScopeFromEnvVariables();\n\n // If users opt-out of this, they _have_ to set up OpenTelemetry themselves\n // There is no way to use this SDK without OpenTelemetry!\n if (!options.skipOpenTelemetrySetup) {\n initOpenTelemetry(client, {\n spanProcessors: options.openTelemetrySpanProcessors,\n });\n validateOpenTelemetrySetup();\n }\n\n enhanceDscWithOpenTelemetryRootSpanName(client);\n setupEventContextTrace(client);\n\n return client;\n}\n\n/**\n * Validate that your OpenTelemetry setup is correct.\n */\nexport function validateOpenTelemetrySetup(): void {\n if (!DEBUG_BUILD) {\n return;\n }\n\n const setup = openTelemetrySetupCheck();\n\n const required: ReturnType<typeof openTelemetrySetupCheck> = ['SentryContextManager', 'SentryPropagator'];\n\n if (hasSpansEnabled()) {\n required.push('SentrySpanProcessor');\n }\n\n for (const k of required) {\n if (!setup.includes(k)) {\n logger.error(\n `You have to set up the ${k}. Without this, the OpenTelemetry & Sentry integration will not work properly.`,\n );\n }\n }\n\n if (!setup.includes('SentrySampler')) {\n logger.warn(\n 'You have to set up the SentrySampler. Without this, the OpenTelemetry & Sentry integration may still work, but sample rates set for the Sentry SDK will not be respected. If you use a custom sampler, make sure to use `wrapSamplingDecision`.',\n );\n }\n}\n\nfunction getClientOptions(\n options: NodeOptions,\n getDefaultIntegrationsImpl: (options: Options) => Integration[],\n): NodeClientOptions {\n const release = getRelease(options.release);\n const spotlight =\n options.spotlight ?? envToBool(process.env.SENTRY_SPOTLIGHT, { strict: true }) ?? process.env.SENTRY_SPOTLIGHT;\n const tracesSampleRate = getTracesSampleRate(options.tracesSampleRate);\n\n const mergedOptions = {\n ...options,\n dsn: options.dsn ?? process.env.SENTRY_DSN,\n environment: options.environment ?? process.env.SENTRY_ENVIRONMENT,\n sendClientReports: options.sendClientReports ?? true,\n transport: options.transport ?? makeNodeTransport,\n stackParser: stackParserFromStackParserOptions(options.stackParser || defaultStackParser),\n release,\n tracesSampleRate,\n spotlight,\n debug: envToBool(options.debug ?? process.env.SENTRY_DEBUG),\n };\n\n const integrations = options.integrations;\n const defaultIntegrations = options.defaultIntegrations ?? getDefaultIntegrationsImpl(mergedOptions);\n\n return {\n ...mergedOptions,\n integrations: getIntegrationsToSetup({\n defaultIntegrations,\n integrations,\n }),\n };\n}\n\nfunction getRelease(release: NodeOptions['release']): string | undefined {\n if (release !== undefined) {\n return release;\n }\n\n const detectedRelease = getSentryRelease();\n if (detectedRelease !== undefined) {\n return detectedRelease;\n }\n\n return undefined;\n}\n\nfunction getTracesSampleRate(tracesSampleRate: NodeOptions['tracesSampleRate']): number | undefined {\n if (tracesSampleRate !== undefined) {\n return tracesSampleRate;\n }\n\n const sampleRateFromEnv = process.env.SENTRY_TRACES_SAMPLE_RATE;\n if (!sampleRateFromEnv) {\n return undefined;\n }\n\n const parsed = parseFloat(sampleRateFromEnv);\n return isFinite(parsed) ? parsed : undefined;\n}\n\n/**\n * Update scope and propagation context based on environmental variables.\n *\n * See https://github.com/getsentry/rfcs/blob/main/text/0071-continue-trace-over-process-boundaries.md\n * for more details.\n */\nfunction updateScopeFromEnvVariables(): void {\n if (envToBool(process.env.SENTRY_USE_ENVIRONMENT) !== false) {\n const sentryTraceEnv = process.env.SENTRY_TRACE;\n const baggageEnv = process.env.SENTRY_BAGGAGE;\n const propagationContext = propagationContextFromHeaders(sentryTraceEnv, baggageEnv);\n getCurrentScope().setPropagationContext(propagationContext);\n }\n}\n"],"names":["isCjs","modulesIntegration","inboundFiltersIntegration","functionToStringIntegration","linkedErrorsIntegration","requestDataIntegration","consoleIntegration","httpIntegration","nativeNodeFetchIntegration","onUncaughtExceptionIntegration","onUnhandledRejectionIntegration","contextLinesIntegration","localVariablesIntegration","nodeContextIntegration","childProcessIntegration","processSessionIntegration","hasSpansEnabled","getAutoPerformanceIntegrations","DEBUG_BUILD","logger","consoleSandbox","maybeInitializeEsmLoader","setOpenTelemetryContextAsyncContextStrategy","getCurrentScope","SPOTLIGHT_INTEGRATION_NAME","spotlightIntegration","client","NodeClient","initOpenTelemetry","enhanceDscWithOpenTelemetryRootSpanName","setupEventContextTrace","openTelemetrySetupCheck","envToBool","makeNodeTransport","stackParserFromStackParserOptions","defaultStackParser","getIntegrationsToSetup","getSentryRelease","propagationContextFromHeaders"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/sdk/index.ts"],"sourcesContent":["import type { Integration, Options } from '@sentry/core';\nimport {\n consoleIntegration,\n consoleSandbox,\n functionToStringIntegration,\n getCurrentScope,\n getIntegrationsToSetup,\n hasSpansEnabled,\n inboundFiltersIntegration,\n linkedErrorsIntegration,\n logger,\n propagationContextFromHeaders,\n requestDataIntegration,\n stackParserFromStackParserOptions,\n} from '@sentry/core';\nimport {\n enhanceDscWithOpenTelemetryRootSpanName,\n openTelemetrySetupCheck,\n setOpenTelemetryContextAsyncContextStrategy,\n setupEventContextTrace,\n} from '@sentry/opentelemetry';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { childProcessIntegration } from '../integrations/childProcess';\nimport { nodeContextIntegration } from '../integrations/context';\nimport { contextLinesIntegration } from '../integrations/contextlines';\nimport { httpIntegration } from '../integrations/http';\nimport { localVariablesIntegration } from '../integrations/local-variables';\nimport { modulesIntegration } from '../integrations/modules';\nimport { nativeNodeFetchIntegration } from '../integrations/node-fetch';\nimport { onUncaughtExceptionIntegration } from '../integrations/onuncaughtexception';\nimport { onUnhandledRejectionIntegration } from '../integrations/onunhandledrejection';\nimport { processSessionIntegration } from '../integrations/processSession';\nimport { INTEGRATION_NAME as SPOTLIGHT_INTEGRATION_NAME, spotlightIntegration } from '../integrations/spotlight';\nimport { getAutoPerformanceIntegrations } from '../integrations/tracing';\nimport { makeNodeTransport } from '../transports';\nimport type { NodeClientOptions, NodeOptions } from '../types';\nimport { isCjs } from '../utils/commonjs';\nimport { envToBool } from '../utils/envToBool';\nimport { defaultStackParser, getSentryRelease } from './api';\nimport { NodeClient } from './client';\nimport { initOpenTelemetry, maybeInitializeEsmLoader } from './initOtel';\n\nfunction getCjsOnlyIntegrations(): Integration[] {\n return isCjs() ? [modulesIntegration()] : [];\n}\n\n/**\n * Get default integrations, excluding performance.\n */\nexport function getDefaultIntegrationsWithoutPerformance(): Integration[] {\n return [\n // Common\n // TODO(v10): Replace with `eventFiltersIntegration` once we remove the deprecated `inboundFiltersIntegration`\n // eslint-disable-next-line deprecation/deprecation\n inboundFiltersIntegration(),\n functionToStringIntegration(),\n linkedErrorsIntegration(),\n requestDataIntegration(),\n // Native Wrappers\n consoleIntegration(),\n httpIntegration(),\n nativeNodeFetchIntegration(),\n // Global Handlers\n onUncaughtExceptionIntegration(),\n onUnhandledRejectionIntegration(),\n // Event Info\n contextLinesIntegration(),\n localVariablesIntegration(),\n nodeContextIntegration(),\n childProcessIntegration(),\n processSessionIntegration(),\n ...getCjsOnlyIntegrations(),\n ];\n}\n\n/** Get the default integrations for the Node SDK. */\nexport function getDefaultIntegrations(options: Options): Integration[] {\n return [\n ...getDefaultIntegrationsWithoutPerformance(),\n // We only add performance integrations if tracing is enabled\n // Note that this means that without tracing enabled, e.g. `expressIntegration()` will not be added\n // This means that generally request isolation will work (because that is done by httpIntegration)\n // But `transactionName` will not be set automatically\n ...(hasSpansEnabled(options) ? getAutoPerformanceIntegrations() : []),\n ];\n}\n\n/**\n * Initialize Sentry for Node.\n */\nexport function init(options: NodeOptions | undefined = {}): NodeClient | undefined {\n return _init(options, getDefaultIntegrations);\n}\n\n/**\n * Initialize Sentry for Node, without any integrations added by default.\n */\nexport function initWithoutDefaultIntegrations(options: NodeOptions | undefined = {}): NodeClient {\n return _init(options, () => []);\n}\n\n/**\n * Initialize Sentry for Node, without performance instrumentation.\n */\nfunction _init(\n _options: NodeOptions | undefined = {},\n getDefaultIntegrationsImpl: (options: Options) => Integration[],\n): NodeClient {\n const options = getClientOptions(_options, getDefaultIntegrationsImpl);\n\n if (options.debug === true) {\n if (DEBUG_BUILD) {\n logger.enable();\n } else {\n // use `console.warn` rather than `logger.warn` since by non-debug bundles have all `logger.x` statements stripped\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn('[Sentry] Cannot initialize SDK with `debug` option using a non-debug bundle.');\n });\n }\n }\n\n if (!isCjs() && options.registerEsmLoaderHooks !== false) {\n maybeInitializeEsmLoader();\n }\n\n setOpenTelemetryContextAsyncContextStrategy();\n\n const scope = getCurrentScope();\n scope.update(options.initialScope);\n\n if (options.spotlight && !options.integrations.some(({ name }) => name === SPOTLIGHT_INTEGRATION_NAME)) {\n options.integrations.push(\n spotlightIntegration({\n sidecarUrl: typeof options.spotlight === 'string' ? options.spotlight : undefined,\n }),\n );\n }\n\n const client = new NodeClient(options);\n // The client is on the current scope, from where it generally is inherited\n getCurrentScope().setClient(client);\n\n client.init();\n\n logger.log(`Running in ${isCjs() ? 'CommonJS' : 'ESM'} mode.`);\n\n client.startClientReportTracking();\n\n updateScopeFromEnvVariables();\n\n // If users opt-out of this, they _have_ to set up OpenTelemetry themselves\n // There is no way to use this SDK without OpenTelemetry!\n if (!options.skipOpenTelemetrySetup) {\n initOpenTelemetry(client, {\n spanProcessors: options.openTelemetrySpanProcessors,\n });\n validateOpenTelemetrySetup();\n }\n\n enhanceDscWithOpenTelemetryRootSpanName(client);\n setupEventContextTrace(client);\n\n return client;\n}\n\n/**\n * Validate that your OpenTelemetry setup is correct.\n */\nexport function validateOpenTelemetrySetup(): void {\n if (!DEBUG_BUILD) {\n return;\n }\n\n const setup = openTelemetrySetupCheck();\n\n const required: ReturnType<typeof openTelemetrySetupCheck> = ['SentryContextManager', 'SentryPropagator'];\n\n if (hasSpansEnabled()) {\n required.push('SentrySpanProcessor');\n }\n\n for (const k of required) {\n if (!setup.includes(k)) {\n logger.error(\n `You have to set up the ${k}. Without this, the OpenTelemetry & Sentry integration will not work properly.`,\n );\n }\n }\n\n if (!setup.includes('SentrySampler')) {\n logger.warn(\n 'You have to set up the SentrySampler. Without this, the OpenTelemetry & Sentry integration may still work, but sample rates set for the Sentry SDK will not be respected. If you use a custom sampler, make sure to use `wrapSamplingDecision`.',\n );\n }\n}\n\nfunction getClientOptions(\n options: NodeOptions,\n getDefaultIntegrationsImpl: (options: Options) => Integration[],\n): NodeClientOptions {\n const release = getRelease(options.release);\n const spotlight =\n options.spotlight ?? envToBool(process.env.SENTRY_SPOTLIGHT, { strict: true }) ?? process.env.SENTRY_SPOTLIGHT;\n const tracesSampleRate = getTracesSampleRate(options.tracesSampleRate);\n\n const mergedOptions = {\n ...options,\n dsn: options.dsn ?? process.env.SENTRY_DSN,\n environment: options.environment ?? process.env.SENTRY_ENVIRONMENT,\n sendClientReports: options.sendClientReports ?? true,\n transport: options.transport ?? makeNodeTransport,\n stackParser: stackParserFromStackParserOptions(options.stackParser || defaultStackParser),\n release,\n tracesSampleRate,\n spotlight,\n debug: envToBool(options.debug ?? process.env.SENTRY_DEBUG),\n };\n\n const integrations = options.integrations;\n const defaultIntegrations = options.defaultIntegrations ?? getDefaultIntegrationsImpl(mergedOptions);\n\n return {\n ...mergedOptions,\n integrations: getIntegrationsToSetup({\n defaultIntegrations,\n integrations,\n }),\n };\n}\n\nfunction getRelease(release: NodeOptions['release']): string | undefined {\n if (release !== undefined) {\n return release;\n }\n\n const detectedRelease = getSentryRelease();\n if (detectedRelease !== undefined) {\n return detectedRelease;\n }\n\n return undefined;\n}\n\nfunction getTracesSampleRate(tracesSampleRate: NodeOptions['tracesSampleRate']): number | undefined {\n if (tracesSampleRate !== undefined) {\n return tracesSampleRate;\n }\n\n const sampleRateFromEnv = process.env.SENTRY_TRACES_SAMPLE_RATE;\n if (!sampleRateFromEnv) {\n return undefined;\n }\n\n const parsed = parseFloat(sampleRateFromEnv);\n return isFinite(parsed) ? parsed : undefined;\n}\n\n/**\n * Update scope and propagation context based on environmental variables.\n *\n * See https://github.com/getsentry/rfcs/blob/main/text/0071-continue-trace-over-process-boundaries.md\n * for more details.\n */\nfunction updateScopeFromEnvVariables(): void {\n if (envToBool(process.env.SENTRY_USE_ENVIRONMENT) !== false) {\n const sentryTraceEnv = process.env.SENTRY_TRACE;\n const baggageEnv = process.env.SENTRY_BAGGAGE;\n const propagationContext = propagationContextFromHeaders(sentryTraceEnv, baggageEnv);\n getCurrentScope().setPropagationContext(propagationContext);\n }\n}\n"],"names":["isCjs","modulesIntegration","inboundFiltersIntegration","functionToStringIntegration","linkedErrorsIntegration","requestDataIntegration","consoleIntegration","httpIntegration","nativeNodeFetchIntegration","onUncaughtExceptionIntegration","onUnhandledRejectionIntegration","contextLinesIntegration","localVariablesIntegration","nodeContextIntegration","childProcessIntegration","processSessionIntegration","hasSpansEnabled","getAutoPerformanceIntegrations","DEBUG_BUILD","logger","consoleSandbox","maybeInitializeEsmLoader","setOpenTelemetryContextAsyncContextStrategy","getCurrentScope","SPOTLIGHT_INTEGRATION_NAME","spotlightIntegration","client","NodeClient","initOpenTelemetry","enhanceDscWithOpenTelemetryRootSpanName","setupEventContextTrace","openTelemetrySetupCheck","envToBool","makeNodeTransport","stackParserFromStackParserOptions","defaultStackParser","getIntegrationsToSetup","getSentryRelease","propagationContextFromHeaders"],"mappings":"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"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
|
|
3
|
-
const moduleModule = require('module');
|
|
4
3
|
const api = require('@opentelemetry/api');
|
|
5
4
|
const resources = require('@opentelemetry/resources');
|
|
6
5
|
const sdkTraceBase = require('@opentelemetry/sdk-trace-base');
|
|
@@ -8,6 +7,7 @@ const semanticConventions = require('@opentelemetry/semantic-conventions');
|
|
|
8
7
|
const core = require('@sentry/core');
|
|
9
8
|
const opentelemetry = require('@sentry/opentelemetry');
|
|
10
9
|
const importInTheMiddle = require('import-in-the-middle');
|
|
10
|
+
const moduleModule = require('module');
|
|
11
11
|
const debugBuild = require('../debug-build.js');
|
|
12
12
|
const index = require('../integrations/tracing/index.js');
|
|
13
13
|
const contextManager = require('../otel/contextManager.js');
|
|
@@ -34,7 +34,7 @@ function maybeInitializeEsmLoader() {
|
|
|
34
34
|
const [nodeMajor = 0, nodeMinor = 0] = process.versions.node.split('.').map(Number);
|
|
35
35
|
|
|
36
36
|
// Register hook was added in v20.6.0 and v18.19.0
|
|
37
|
-
if (nodeMajor >=
|
|
37
|
+
if (nodeMajor >= 21 || (nodeMajor === 20 && nodeMinor >= 6) || (nodeMajor === 18 && nodeMinor >= 19)) {
|
|
38
38
|
if (!core.GLOBAL_OBJ._sentryEsmLoaderHookRegistered) {
|
|
39
39
|
try {
|
|
40
40
|
const { addHookMessagePort } = importInTheMiddle.createAddHookMessageChannel();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initOtel.js","sources":["../../../src/sdk/initOtel.ts"],"sourcesContent":["import moduleModule from 'module';\nimport { DiagLogLevel, context, diag, propagation, trace } from '@opentelemetry/api';\nimport { Resource } from '@opentelemetry/resources';\nimport type { SpanProcessor } from '@opentelemetry/sdk-trace-base';\nimport { BasicTracerProvider } from '@opentelemetry/sdk-trace-base';\nimport {\n ATTR_SERVICE_NAME,\n ATTR_SERVICE_VERSION,\n SEMRESATTRS_SERVICE_NAMESPACE,\n} from '@opentelemetry/semantic-conventions';\nimport { GLOBAL_OBJ, SDK_VERSION, consoleSandbox, logger } from '@sentry/core';\nimport { SentryPropagator, SentrySampler, SentrySpanProcessor } from '@sentry/opentelemetry';\nimport { createAddHookMessageChannel } from 'import-in-the-middle';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { getOpenTelemetryInstrumentationToPreload } from '../integrations/tracing';\nimport { SentryContextManager } from '../otel/contextManager';\nimport { isCjs } from '../utils/commonjs';\nimport type { NodeClient } from './client';\n\n// About 277h - this must fit into new Array(len)!\nconst MAX_MAX_SPAN_WAIT_DURATION = 1_000_000;\n\ninterface AdditionalOpenTelemetryOptions {\n /** Additional SpanProcessor instances that should be used. */\n spanProcessors?: SpanProcessor[];\n}\n\n/**\n * Initialize OpenTelemetry for Node.\n */\nexport function initOpenTelemetry(client: NodeClient, options: AdditionalOpenTelemetryOptions = {}): void {\n if (client.getOptions().debug) {\n setupOpenTelemetryLogger();\n }\n\n const provider = setupOtel(client, options);\n client.traceProvider = provider;\n}\n\n/** Initialize the ESM loader. */\nexport function maybeInitializeEsmLoader(): void {\n const [nodeMajor = 0, nodeMinor = 0] = process.versions.node.split('.').map(Number);\n\n // Register hook was added in v20.6.0 and v18.19.0\n if (nodeMajor >= 22 || (nodeMajor === 20 && nodeMinor >= 6) || (nodeMajor === 18 && nodeMinor >= 19)) {\n if (!GLOBAL_OBJ._sentryEsmLoaderHookRegistered) {\n try {\n const { addHookMessagePort } = createAddHookMessageChannel();\n // @ts-expect-error register is available in these versions\n moduleModule.register('import-in-the-middle/hook.mjs', import.meta.url, {\n data: { addHookMessagePort, include: [] },\n transferList: [addHookMessagePort],\n });\n } catch (error) {\n logger.warn('Failed to register ESM hook', error);\n }\n }\n } else {\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn(\n '[Sentry] You are using Node.js in ESM mode (\"import syntax\"). The Sentry Node.js SDK is not compatible with ESM in Node.js versions before 18.19.0 or before 20.6.0. Please either build your application with CommonJS (\"require() syntax\"), or upgrade your Node.js version.',\n );\n });\n }\n}\n\ninterface NodePreloadOptions {\n debug?: boolean;\n integrations?: string[];\n}\n\n/**\n * Preload OpenTelemetry for Node.\n * This can be used to preload instrumentation early, but set up Sentry later.\n * By preloading the OTEL instrumentation wrapping still happens early enough that everything works.\n */\nexport function preloadOpenTelemetry(options: NodePreloadOptions = {}): void {\n const { debug } = options;\n\n if (debug) {\n logger.enable();\n setupOpenTelemetryLogger();\n }\n\n if (!isCjs()) {\n maybeInitializeEsmLoader();\n }\n\n // These are all integrations that we need to pre-load to ensure they are set up before any other code runs\n getPreloadMethods(options.integrations).forEach(fn => {\n fn();\n\n if (debug) {\n logger.log(`[Sentry] Preloaded ${fn.id} instrumentation`);\n }\n });\n}\n\nfunction getPreloadMethods(integrationNames?: string[]): ((() => void) & { id: string })[] {\n const instruments = getOpenTelemetryInstrumentationToPreload();\n\n if (!integrationNames) {\n return instruments;\n }\n\n return instruments.filter(instrumentation => integrationNames.includes(instrumentation.id));\n}\n\n/** Just exported for tests. */\nexport function setupOtel(client: NodeClient, options: AdditionalOpenTelemetryOptions = {}): BasicTracerProvider {\n // Create and configure NodeTracerProvider\n const provider = new BasicTracerProvider({\n sampler: new SentrySampler(client),\n resource: new Resource({\n [ATTR_SERVICE_NAME]: 'node',\n // eslint-disable-next-line deprecation/deprecation\n [SEMRESATTRS_SERVICE_NAMESPACE]: 'sentry',\n [ATTR_SERVICE_VERSION]: SDK_VERSION,\n }),\n forceFlushTimeoutMillis: 500,\n spanProcessors: [\n new SentrySpanProcessor({\n timeout: _clampSpanProcessorTimeout(client.getOptions().maxSpanWaitDuration),\n }),\n ...(options.spanProcessors || []),\n ],\n });\n\n // Register as globals\n trace.setGlobalTracerProvider(provider);\n propagation.setGlobalPropagator(new SentryPropagator());\n context.setGlobalContextManager(new SentryContextManager());\n\n return provider;\n}\n\n/** Just exported for tests. */\nexport function _clampSpanProcessorTimeout(maxSpanWaitDuration: number | undefined): number | undefined {\n if (maxSpanWaitDuration == null) {\n return undefined;\n }\n\n // We guard for a max. value here, because we create an array with this length\n // So if this value is too large, this would fail\n if (maxSpanWaitDuration > MAX_MAX_SPAN_WAIT_DURATION) {\n DEBUG_BUILD &&\n logger.warn(`\\`maxSpanWaitDuration\\` is too high, using the maximum value of ${MAX_MAX_SPAN_WAIT_DURATION}`);\n return MAX_MAX_SPAN_WAIT_DURATION;\n } else if (maxSpanWaitDuration <= 0 || Number.isNaN(maxSpanWaitDuration)) {\n DEBUG_BUILD && logger.warn('`maxSpanWaitDuration` must be a positive number, using default value instead.');\n return undefined;\n }\n\n return maxSpanWaitDuration;\n}\n\n/**\n * Setup the OTEL logger to use our own logger.\n */\nfunction setupOpenTelemetryLogger(): void {\n const otelLogger = new Proxy(logger as typeof logger & { verbose: (typeof logger)['debug'] }, {\n get(target, prop, receiver) {\n const actualProp = prop === 'verbose' ? 'debug' : prop;\n return Reflect.get(target, actualProp, receiver);\n },\n });\n\n // Disable diag, to ensure this works even if called multiple times\n diag.disable();\n diag.setLogger(otelLogger, DiagLogLevel.DEBUG);\n}\n"],"names":["GLOBAL_OBJ","createAddHookMessageChannel","moduleModule","logger","consoleSandbox","isCjs","getOpenTelemetryInstrumentationToPreload","BasicTracerProvider","SentrySampler","Resource","ATTR_SERVICE_NAME","SEMRESATTRS_SERVICE_NAMESPACE","ATTR_SERVICE_VERSION","SDK_VERSION","SentrySpanProcessor","trace","propagation","SentryPropagator","context","SentryContextManager","DEBUG_BUILD","diag","DiagLogLevel"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"initOtel.js","sources":["../../../src/sdk/initOtel.ts"],"sourcesContent":["import { context, diag, DiagLogLevel, propagation, trace } from '@opentelemetry/api';\nimport { Resource } from '@opentelemetry/resources';\nimport type { SpanProcessor } from '@opentelemetry/sdk-trace-base';\nimport { BasicTracerProvider } from '@opentelemetry/sdk-trace-base';\nimport {\n ATTR_SERVICE_NAME,\n ATTR_SERVICE_VERSION,\n SEMRESATTRS_SERVICE_NAMESPACE,\n} from '@opentelemetry/semantic-conventions';\nimport { consoleSandbox, GLOBAL_OBJ, logger, SDK_VERSION } from '@sentry/core';\nimport { SentryPropagator, SentrySampler, SentrySpanProcessor } from '@sentry/opentelemetry';\nimport { createAddHookMessageChannel } from 'import-in-the-middle';\nimport moduleModule from 'module';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { getOpenTelemetryInstrumentationToPreload } from '../integrations/tracing';\nimport { SentryContextManager } from '../otel/contextManager';\nimport { isCjs } from '../utils/commonjs';\nimport type { NodeClient } from './client';\n\n// About 277h - this must fit into new Array(len)!\nconst MAX_MAX_SPAN_WAIT_DURATION = 1_000_000;\n\ninterface AdditionalOpenTelemetryOptions {\n /** Additional SpanProcessor instances that should be used. */\n spanProcessors?: SpanProcessor[];\n}\n\n/**\n * Initialize OpenTelemetry for Node.\n */\nexport function initOpenTelemetry(client: NodeClient, options: AdditionalOpenTelemetryOptions = {}): void {\n if (client.getOptions().debug) {\n setupOpenTelemetryLogger();\n }\n\n const provider = setupOtel(client, options);\n client.traceProvider = provider;\n}\n\n/** Initialize the ESM loader. */\nexport function maybeInitializeEsmLoader(): void {\n const [nodeMajor = 0, nodeMinor = 0] = process.versions.node.split('.').map(Number);\n\n // Register hook was added in v20.6.0 and v18.19.0\n if (nodeMajor >= 21 || (nodeMajor === 20 && nodeMinor >= 6) || (nodeMajor === 18 && nodeMinor >= 19)) {\n if (!GLOBAL_OBJ._sentryEsmLoaderHookRegistered) {\n try {\n const { addHookMessagePort } = createAddHookMessageChannel();\n // @ts-expect-error register is available in these versions\n moduleModule.register('import-in-the-middle/hook.mjs', import.meta.url, {\n data: { addHookMessagePort, include: [] },\n transferList: [addHookMessagePort],\n });\n } catch (error) {\n logger.warn('Failed to register ESM hook', error);\n }\n }\n } else {\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn(\n '[Sentry] You are using Node.js in ESM mode (\"import syntax\"). The Sentry Node.js SDK is not compatible with ESM in Node.js versions before 18.19.0 or before 20.6.0. Please either build your application with CommonJS (\"require() syntax\"), or upgrade your Node.js version.',\n );\n });\n }\n}\n\ninterface NodePreloadOptions {\n debug?: boolean;\n integrations?: string[];\n}\n\n/**\n * Preload OpenTelemetry for Node.\n * This can be used to preload instrumentation early, but set up Sentry later.\n * By preloading the OTEL instrumentation wrapping still happens early enough that everything works.\n */\nexport function preloadOpenTelemetry(options: NodePreloadOptions = {}): void {\n const { debug } = options;\n\n if (debug) {\n logger.enable();\n setupOpenTelemetryLogger();\n }\n\n if (!isCjs()) {\n maybeInitializeEsmLoader();\n }\n\n // These are all integrations that we need to pre-load to ensure they are set up before any other code runs\n getPreloadMethods(options.integrations).forEach(fn => {\n fn();\n\n if (debug) {\n logger.log(`[Sentry] Preloaded ${fn.id} instrumentation`);\n }\n });\n}\n\nfunction getPreloadMethods(integrationNames?: string[]): ((() => void) & { id: string })[] {\n const instruments = getOpenTelemetryInstrumentationToPreload();\n\n if (!integrationNames) {\n return instruments;\n }\n\n return instruments.filter(instrumentation => integrationNames.includes(instrumentation.id));\n}\n\n/** Just exported for tests. */\nexport function setupOtel(client: NodeClient, options: AdditionalOpenTelemetryOptions = {}): BasicTracerProvider {\n // Create and configure NodeTracerProvider\n const provider = new BasicTracerProvider({\n sampler: new SentrySampler(client),\n resource: new Resource({\n [ATTR_SERVICE_NAME]: 'node',\n // eslint-disable-next-line deprecation/deprecation\n [SEMRESATTRS_SERVICE_NAMESPACE]: 'sentry',\n [ATTR_SERVICE_VERSION]: SDK_VERSION,\n }),\n forceFlushTimeoutMillis: 500,\n spanProcessors: [\n new SentrySpanProcessor({\n timeout: _clampSpanProcessorTimeout(client.getOptions().maxSpanWaitDuration),\n }),\n ...(options.spanProcessors || []),\n ],\n });\n\n // Register as globals\n trace.setGlobalTracerProvider(provider);\n propagation.setGlobalPropagator(new SentryPropagator());\n context.setGlobalContextManager(new SentryContextManager());\n\n return provider;\n}\n\n/** Just exported for tests. */\nexport function _clampSpanProcessorTimeout(maxSpanWaitDuration: number | undefined): number | undefined {\n if (maxSpanWaitDuration == null) {\n return undefined;\n }\n\n // We guard for a max. value here, because we create an array with this length\n // So if this value is too large, this would fail\n if (maxSpanWaitDuration > MAX_MAX_SPAN_WAIT_DURATION) {\n DEBUG_BUILD &&\n logger.warn(`\\`maxSpanWaitDuration\\` is too high, using the maximum value of ${MAX_MAX_SPAN_WAIT_DURATION}`);\n return MAX_MAX_SPAN_WAIT_DURATION;\n } else if (maxSpanWaitDuration <= 0 || Number.isNaN(maxSpanWaitDuration)) {\n DEBUG_BUILD && logger.warn('`maxSpanWaitDuration` must be a positive number, using default value instead.');\n return undefined;\n }\n\n return maxSpanWaitDuration;\n}\n\n/**\n * Setup the OTEL logger to use our own logger.\n */\nfunction setupOpenTelemetryLogger(): void {\n const otelLogger = new Proxy(logger as typeof logger & { verbose: (typeof logger)['debug'] }, {\n get(target, prop, receiver) {\n const actualProp = prop === 'verbose' ? 'debug' : prop;\n return Reflect.get(target, actualProp, receiver);\n },\n });\n\n // Disable diag, to ensure this works even if called multiple times\n diag.disable();\n diag.setLogger(otelLogger, DiagLogLevel.DEBUG);\n}\n"],"names":["GLOBAL_OBJ","createAddHookMessageChannel","moduleModule","logger","consoleSandbox","isCjs","getOpenTelemetryInstrumentationToPreload","BasicTracerProvider","SentrySampler","Resource","ATTR_SERVICE_NAME","SEMRESATTRS_SERVICE_NAMESPACE","ATTR_SERVICE_VERSION","SDK_VERSION","SentrySpanProcessor","trace","propagation","SentryPropagator","context","SentryContextManager","DEBUG_BUILD","diag","DiagLogLevel"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"addOriginToSpan.js","sources":["../../../src/utils/addOriginToSpan.ts"],"sourcesContent":["import type { Span } from '@opentelemetry/api';\nimport {
|
|
1
|
+
{"version":3,"file":"addOriginToSpan.js","sources":["../../../src/utils/addOriginToSpan.ts"],"sourcesContent":["import type { Span } from '@opentelemetry/api';\nimport type { SpanOrigin } from '@sentry/core';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core';\n\n/** Adds an origin to an OTEL Span. */\nexport function addOriginToSpan(span: Span, origin: SpanOrigin): void {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, origin);\n}\n"],"names":["SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN"],"mappings":";;;;AAIA;AACO,SAAS,eAAe,CAAC,IAAI,EAAQ,MAAM,EAAoB;AACtE,EAAE,IAAI,CAAC,YAAY,CAACA,qCAAgC,EAAE,MAAM,CAAC;AAC7D;;;;"}
|
package/build/esm/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import * as exports from './logs/exports.js';
|
|
2
|
+
export { exports as logger };
|
|
1
3
|
export { httpIntegration } from './integrations/http/index.js';
|
|
2
4
|
export { nativeNodeFetchIntegration } from './integrations/node-fetch/index.js';
|
|
3
5
|
export { fsIntegration } from './integrations/fs.js';
|
|
@@ -43,7 +45,5 @@ export { makeNodeTransport } from './transports/http.js';
|
|
|
43
45
|
export { NodeClient } from './sdk/client.js';
|
|
44
46
|
export { cron } from './cron/index.js';
|
|
45
47
|
export { setOpenTelemetryContextAsyncContextStrategy as setNodeAsyncContextStrategy } from '@sentry/opentelemetry';
|
|
46
|
-
export { SDK_VERSION, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, Scope, addBreadcrumb, addEventProcessor, addIntegration, captureCheckIn, captureConsoleIntegration, captureEvent, captureException, captureFeedback, captureMessage, captureSession, close, consoleIntegration, consoleLoggingIntegration, continueTrace, createTransport, dedupeIntegration, endSession, eventFiltersIntegration, extraErrorDataIntegration, flush, functionToStringIntegration, getActiveSpan, getClient, getCurrentScope, getGlobalScope, getIsolationScope, getRootSpan, getSpanDescendants, getSpanStatusFromHttpCode, getTraceData, getTraceMetaTags, inboundFiltersIntegration, isInitialized, lastEventId, linkedErrorsIntegration, parameterize, profiler, requestDataIntegration, rewriteFramesIntegration, setContext, setCurrentClient, setExtra, setExtras, setHttpStatus, setMeasurement, setTag, setTags, setUser, spanToBaggageHeader, spanToJSON, spanToTraceHeader, startInactiveSpan, startNewTrace, startSession, startSpan, startSpanManual, suppressTracing, trpcMiddleware, updateSpanName, withActiveSpan, withIsolationScope, withMonitor, withScope, zodErrorsIntegration } from '@sentry/core';
|
|
47
|
-
import * as exports from './logs/exports.js';
|
|
48
|
-
export { exports as logger };
|
|
48
|
+
export { SDK_VERSION, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, Scope, addBreadcrumb, addEventProcessor, addIntegration, captureCheckIn, captureConsoleIntegration, captureEvent, captureException, captureFeedback, captureMessage, captureSession, close, consoleIntegration, consoleLoggingIntegration, continueTrace, createTransport, dedupeIntegration, endSession, eventFiltersIntegration, extraErrorDataIntegration, flush, functionToStringIntegration, getActiveSpan, getClient, getCurrentScope, getGlobalScope, getIsolationScope, getRootSpan, getSpanDescendants, getSpanStatusFromHttpCode, getTraceData, getTraceMetaTags, inboundFiltersIntegration, instrumentSupabaseClient, isInitialized, lastEventId, linkedErrorsIntegration, parameterize, profiler, requestDataIntegration, rewriteFramesIntegration, setContext, setCurrentClient, setExtra, setExtras, setHttpStatus, setMeasurement, setTag, setTags, setUser, spanToBaggageHeader, spanToJSON, spanToTraceHeader, startInactiveSpan, startNewTrace, startSession, startSpan, startSpanManual, supabaseIntegration, suppressTracing, trpcMiddleware, updateSpanName, withActiveSpan, withIsolationScope, withMonitor, withScope, wrapMcpServerWithSentry, zodErrorsIntegration } from '@sentry/core';
|
|
49
49
|
//# sourceMappingURL=index.js.map
|
|
@@ -7,7 +7,7 @@ import { isDebuggerEnabled } from '../../utils/debug.js';
|
|
|
7
7
|
const { isPromise } = types;
|
|
8
8
|
|
|
9
9
|
// This string is a placeholder that gets overwritten with the worker code.
|
|
10
|
-
const base64WorkerScript = 'LyohIEBzZW50cnkvbm9kZSA5LjEzLjAgKDZlNzc1YzYpIHwgaHR0cHM6Ly9naXRodWIuY29tL2dldHNlbnRyeS9zZW50cnktamF2YXNjcmlwdCAqLwppbXBvcnR7U2Vzc2lvbiBhcyB0fWZyb20ibm9kZTppbnNwZWN0b3IiO2ltcG9ydHt3b3JrZXJEYXRhIGFzIG4scGFyZW50UG9ydCBhcyBlfWZyb20ibm9kZTp3b3JrZXJfdGhyZWFkcyI7aW1wb3J0e3Bvc2l4IGFzIHIsc2VwIGFzIG99ZnJvbSJub2RlOnBhdGgiO2ltcG9ydCphcyBzIGZyb20ibm9kZTpodHRwIjtpbXBvcnQqYXMgaSBmcm9tIm5vZGU6aHR0cHMiO2ltcG9ydHtSZWFkYWJsZSBhcyBjfWZyb20ibm9kZTpzdHJlYW0iO2ltcG9ydHtjcmVhdGVHemlwIGFzIHV9ZnJvbSJub2RlOnpsaWIiO2ltcG9ydCphcyBhIGZyb20ibm9kZTpuZXQiO2ltcG9ydCphcyBmIGZyb20ibm9kZTp0bHMiO2NvbnN0IGg9InVuZGVmaW5lZCI9PXR5cGVvZiBfX1NFTlRSWV9ERUJVR19ffHxfX1NFTlRSWV9ERUJVR19fLHA9Z2xvYmFsVGhpcyxsPSJ1bmRlZmluZWQiPT10eXBlb2YgX19TRU5UUllfREVCVUdfX3x8X19TRU5UUllfREVCVUdfXyxkPSI5LjEzLjAiO2Z1bmN0aW9uIG0oKXtyZXR1cm4gZyhwKSxwfWZ1bmN0aW9uIGcodCl7Y29uc3Qgbj10Ll9fU0VOVFJZX189dC5fX1NFTlRSWV9ffHx7fTtyZXR1cm4gbi52ZXJzaW9uPW4udmVyc2lvbnx8ZCxuW2RdPW5bZF18fHt9fWZ1bmN0aW9uIHkodCxuLGU9cCl7Y29uc3Qgcj1lLl9fU0VOVFJZX189ZS5fX1NFTlRSWV9ffHx7fSxvPXJbZF09cltkXXx8e307cmV0dXJuIG9bdF18fChvW3RdPW4oKSl9Y29uc3QgYj1bImRlYnVnIiwiaW5mbyIsIndhcm4iLCJlcnJvciIsImxvZyIsImFzc2VydCIsInRyYWNlIl0sXz17fTtmdW5jdGlvbiB2KHQpe2lmKCEoImNvbnNvbGUiaW4gcCkpcmV0dXJuIHQoKTtjb25zdCBuPXAuY29uc29sZSxlPXt9LHI9T2JqZWN0LmtleXMoXyk7ci5mb3JFYWNoKCh0PT57Y29uc3Qgcj1fW3RdO2VbdF09blt0XSxuW3RdPXJ9KSk7dHJ5e3JldHVybiB0KCl9ZmluYWxseXtyLmZvckVhY2goKHQ9PntuW3RdPWVbdF19KSl9fWNvbnN0IHc9eSgibG9nZ2VyIiwoZnVuY3Rpb24oKXtsZXQgdD0hMTtjb25zdCBuPXtlbmFibGU6KCk9Pnt0PSEwfSxkaXNhYmxlOigpPT57dD0hMX0saXNFbmFibGVkOigpPT50fTtyZXR1cm4gbD9iLmZvckVhY2goKGU9PntuW2VdPSguLi5uKT0+e3QmJnYoKCgpPT57cC5jb25zb2xlW2VdKGBTZW50cnkgTG9nZ2VyIFske2V9XTpgLC4uLm4pfSkpfX0pKTpiLmZvckVhY2goKHQ9PntuW3RdPSgpPT57fX0pKSxufSkpLFM9NTAsJD0iPyIsRT0vY2FwdHVyZU1lc3NhZ2V8Y2FwdHVyZUV4Y2VwdGlvbi87ZnVuY3Rpb24geCh0KXtyZXR1cm4gdFt0Lmxlbmd0aC0xXXx8e319Y29uc3QgTj0iPGFub255bW91cz4iO2NvbnN0IFQ9MWUzO2Z1bmN0aW9uIEMoKXtyZXR1cm4gRGF0ZS5ub3coKS9UfWNvbnN0IFI9ZnVuY3Rpb24oKXtjb25zdHtwZXJmb3JtYW5jZTp0fT1wO2lmKCF0Py5ub3cpcmV0dXJuIEM7Y29uc3Qgbj1EYXRlLm5vdygpLXQubm93KCksZT1udWxsPT10LnRpbWVPcmlnaW4/bjp0LnRpbWVPcmlnaW47cmV0dXJuKCk9PihlK3Qubm93KCkpL1R9KCksaz1PYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO2Z1bmN0aW9uIGoodCxuKXtyZXR1cm4gay5jYWxsKHQpPT09YFtvYmplY3QgJHtufV1gfWZ1bmN0aW9uIEQodCl7cmV0dXJuIGoodCwiU3RyaW5nIil9ZnVuY3Rpb24gSSh0KXtyZXR1cm4gaih0LCJPYmplY3QiKX1mdW5jdGlvbiBPKHQpe3JldHVybiBCb29sZWFuKHQ/LnRoZW4mJiJmdW5jdGlvbiI9PXR5cGVvZiB0LnRoZW4pfWZ1bmN0aW9uIEEodCxuKXt0cnl7cmV0dXJuIHQgaW5zdGFuY2VvZiBufWNhdGNoKHQpe3JldHVybiExfX1jb25zdCBQPXAsVT04MDtmdW5jdGlvbiBNKHQsbil7Y29uc3QgZT10LHI9W107aWYoIWU/LnRhZ05hbWUpcmV0dXJuIiI7aWYoUC5IVE1MRWxlbWVudCYmZSBpbnN0YW5jZW9mIEhUTUxFbGVtZW50JiZlLmRhdGFzZXQpe2lmKGUuZGF0YXNldC5zZW50cnlDb21wb25lbnQpcmV0dXJuIGUuZGF0YXNldC5zZW50cnlDb21wb25lbnQ7aWYoZS5kYXRhc2V0LnNlbnRyeUVsZW1lbnQpcmV0dXJuIGUuZGF0YXNldC5zZW50cnlFbGVtZW50fXIucHVzaChlLnRhZ05hbWUudG9Mb3dlckNhc2UoKSk7Y29uc3Qgbz1uPy5sZW5ndGg/bi5maWx0ZXIoKHQ9PmUuZ2V0QXR0cmlidXRlKHQpKSkubWFwKCh0PT5bdCxlLmdldEF0dHJpYnV0ZSh0KV0pKTpudWxsO2lmKG8/Lmxlbmd0aClvLmZvckVhY2goKHQ9PntyLnB1c2goYFske3RbMF19PSIke3RbMV19Il1gKX0pKTtlbHNle2UuaWQmJnIucHVzaChgIyR7ZS5pZH1gKTtjb25zdCB0PWUuY2xhc3NOYW1lO2lmKHQmJkQodCkpe2NvbnN0IG49dC5zcGxpdCgvXHMrLyk7Zm9yKGNvbnN0IHQgb2YgbilyLnB1c2goYC4ke3R9YCl9fWNvbnN0IHM9WyJhcmlhLWxhYmVsIiwidHlwZSIsIm5hbWUiLCJ0aXRsZSIsImFsdCJdO2Zvcihjb25zdCB0IG9mIHMpe2NvbnN0IG49ZS5nZXRBdHRyaWJ1dGUodCk7biYmci5wdXNoKGBbJHt0fT0iJHtufSJdYCl9cmV0dXJuIHIuam9pbigiIil9ZnVuY3Rpb24gTCh0LG49MCl7cmV0dXJuInN0cmluZyIhPXR5cGVvZiB0fHwwPT09bnx8dC5sZW5ndGg8PW4/dDpgJHt0LnNsaWNlKDAsbil9Li4uYH1mdW5jdGlvbiBCKHQpe2lmKGZ1bmN0aW9uKHQpe3N3aXRjaChrLmNhbGwodCkpe2Nhc2UiW29iamVjdCBFcnJvcl0iOmNhc2UiW29iamVjdCBFeGNlcHRpb25dIjpjYXNlIltvYmplY3QgRE9NRXhjZXB0aW9uXSI6Y2FzZSJbb2JqZWN0IFdlYkFzc2VtYmx5LkV4Y2VwdGlvbl0iOnJldHVybiEwO2RlZmF1bHQ6cmV0dXJuIEEodCxFcnJvcil9fSh0KSlyZXR1cm57bWVzc2FnZTp0Lm1lc3NhZ2UsbmFtZTp0Lm5hbWUsc3RhY2s6dC5zdGFjaywuLi5KKHQpfTtpZihuPXQsInVuZGVmaW5lZCIhPXR5cGVvZiBFdmVudCYmQShuLEV2ZW50KSl7Y29uc3Qgbj17dHlwZTp0LnR5cGUsdGFyZ2V0OkcodC50YXJnZXQpLGN1cnJlbnRUYXJnZXQ6Ryh0LmN1cnJlbnRUYXJnZXQpLC4uLkoodCl9O3JldHVybiJ1bmRlZmluZWQiIT10eXBlb2YgQ3VzdG9tRXZlbnQmJkEodCxDdXN0b21FdmVudCkmJihuLmRldGFpbD10LmRldGFpbCksbn1yZXR1cm4gdDt2YXIgbn1mdW5jdGlvbiBHKHQpe3RyeXtyZXR1cm4gbj10LCJ1bmRlZmluZWQiIT10eXBlb2YgRWxlbWVudCYmQShuLEVsZW1lbnQpP2Z1bmN0aW9uKHQsbj17fSl7aWYoIXQpcmV0dXJuIjx1bmtub3duPiI7dHJ5e2xldCBlPXQ7Y29uc3Qgcj01LG89W107bGV0IHM9MCxpPTA7Y29uc3QgYz0iID4gIix1PWMubGVuZ3RoO2xldCBhO2NvbnN0IGY9QXJyYXkuaXNBcnJheShuKT9uOm4ua2V5QXR0cnMsaD0hQXJyYXkuaXNBcnJheShuKSYmbi5tYXhTdHJpbmdMZW5ndGh8fFU7Zm9yKDtlJiZzKys8ciYmKGE9TShlLGYpLCEoImh0bWwiPT09YXx8cz4xJiZpK28ubGVuZ3RoKnUrYS5sZW5ndGg+PWgpKTspby5wdXNoKGEpLGkrPWEubGVuZ3RoLGU9ZS5wYXJlbnROb2RlO3JldHVybiBvLnJldmVyc2UoKS5qb2luKGMpfWNhdGNoKHQpe3JldHVybiI8dW5rbm93bj4ifX0odCk6T2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHQpfWNhdGNoKHQpe3JldHVybiI8dW5rbm93bj4ifXZhciBufWZ1bmN0aW9uIEoodCl7aWYoIm9iamVjdCI9PXR5cGVvZiB0JiZudWxsIT09dCl7Y29uc3Qgbj17fTtmb3IoY29uc3QgZSBpbiB0KU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0LGUpJiYobltlXT10W2VdKTtyZXR1cm4gbn1yZXR1cm57fX1mdW5jdGlvbiBZKHQ9ZnVuY3Rpb24oKXtjb25zdCB0PXA7cmV0dXJuIHQuY3J5cHRvfHx0Lm1zQ3J5cHRvfSgpKXtsZXQgbj0oKT0+MTYqTWF0aC5yYW5kb20oKTt0cnl7aWYodD8ucmFuZG9tVVVJRClyZXR1cm4gdC5yYW5kb21VVUlEKCkucmVwbGFjZSgvLS9nLCIiKTt0Py5nZXRSYW5kb21WYWx1ZXMmJihuPSgpPT57Y29uc3Qgbj1uZXcgVWludDhBcnJheSgxKTtyZXR1cm4gdC5nZXRSYW5kb21WYWx1ZXMobiksblswXX0pfWNhdGNoKHQpe31yZXR1cm4oWzFlN10rMWUzKzRlMys4ZTMrMWUxMSkucmVwbGFjZSgvWzAxOF0vZywodD0+KHReKDE1Jm4oKSk+PnQvNCkudG9TdHJpbmcoMTYpKSl9dmFyIHo7ZnVuY3Rpb24gSCh0KXtyZXR1cm4gbmV3IEYoKG49PntuKHQpfSkpfSFmdW5jdGlvbih0KXt0W3QuUEVORElORz0wXT0iUEVORElORyI7dFt0LlJFU09MVkVEPTFdPSJSRVNPTFZFRCI7dFt0LlJFSkVDVEVEPTJdPSJSRUpFQ1RFRCJ9KHp8fCh6PXt9KSk7Y2xhc3MgRntjb25zdHJ1Y3Rvcih0KXt0aGlzLnQ9ei5QRU5ESU5HLHRoaXMubz1bXSx0aGlzLmkodCl9dGhlbih0LG4pe3JldHVybiBuZXcgRigoKGUscik9Pnt0aGlzLm8ucHVzaChbITEsbj0+e2lmKHQpdHJ5e2UodChuKSl9Y2F0Y2godCl7cih0KX1lbHNlIGUobil9LHQ9PntpZihuKXRyeXtlKG4odCkpfWNhdGNoKHQpe3IodCl9ZWxzZSByKHQpfV0pLHRoaXMudSgpfSkpfWNhdGNoKHQpe3JldHVybiB0aGlzLnRoZW4oKHQ9PnQpLHQpfWZpbmFsbHkodCl7cmV0dXJuIG5ldyBGKCgobixlKT0+e2xldCByLG87cmV0dXJuIHRoaXMudGhlbigobj0+e289ITEscj1uLHQmJnQoKX0pLChuPT57bz0hMCxyPW4sdCYmdCgpfSkpLnRoZW4oKCgpPT57bz9lKHIpOm4ocil9KSl9KSl9dSgpe2lmKHRoaXMudD09PXouUEVORElORylyZXR1cm47Y29uc3QgdD10aGlzLm8uc2xpY2UoKTt0aGlzLm89W10sdC5mb3JFYWNoKCh0PT57dFswXXx8KHRoaXMudD09PXouUkVTT0xWRUQmJnRbMV0odGhpcy5oKSx0aGlzLnQ9PT16LlJFSkVDVEVEJiZ0WzJdKHRoaXMuaCksdFswXT0hMCl9KSl9aSh0KXtjb25zdCBuPSh0LG4pPT57dGhpcy50PT09ei5QRU5ESU5HJiYoTyhuKT9uLnRoZW4oZSxyKToodGhpcy50PXQsdGhpcy5oPW4sdGhpcy51KCkpKX0sZT10PT57bih6LlJFU09MVkVELHQpfSxyPXQ9PntuKHouUkVKRUNURUQsdCl9O3RyeXt0KGUscil9Y2F0Y2godCl7cih0KX19fWZ1bmN0aW9uIFcodCl7Y29uc3Qgbj1SKCksZT17c2lkOlkoKSxpbml0OiEwLHRpbWVzdGFtcDpuLHN0YXJ0ZWQ6bixkdXJhdGlvbjowLHN0YXR1czoib2siLGVycm9yczowLGlnbm9yZUR1cmF0aW9uOiExLHRvSlNPTjooKT0+ZnVuY3Rpb24odCl7cmV0dXJue3NpZDpgJHt0LnNpZH1gLGluaXQ6dC5pbml0LHN0YXJ0ZWQ6bmV3IERhdGUoMWUzKnQuc3RhcnRlZCkudG9JU09TdHJpbmcoKSx0aW1lc3RhbXA6bmV3IERhdGUoMWUzKnQudGltZXN0YW1wKS50b0lTT1N0cmluZygpLHN0YXR1czp0LnN0YXR1cyxlcnJvcnM6dC5lcnJvcnMsZGlkOiJudW1iZXIiPT10eXBlb2YgdC5kaWR8fCJzdHJpbmciPT10eXBlb2YgdC5kaWQ/YCR7dC5kaWR9YDp2b2lkIDAsZHVyYXRpb246dC5kdXJhdGlvbixhYm5vcm1hbF9tZWNoYW5pc206dC5hYm5vcm1hbF9tZWNoYW5pc20sYXR0cnM6e3JlbGVhc2U6dC5yZWxlYXNlLGVudmlyb25tZW50OnQuZW52aXJvbm1lbnQsaXBfYWRkcmVzczp0LmlwQWRkcmVzcyx1c2VyX2FnZW50OnQudXNlckFnZW50fX19KGUpfTtyZXR1cm4gdCYmSyhlLHQpLGV9ZnVuY3Rpb24gSyh0LG49e30pe2lmKG4udXNlciYmKCF0LmlwQWRkcmVzcyYmbi51c2VyLmlwX2FkZHJlc3MmJih0LmlwQWRkcmVzcz1uLnVzZXIuaXBfYWRkcmVzcyksdC5kaWR8fG4uZGlkfHwodC5kaWQ9bi51c2VyLmlkfHxuLnVzZXIuZW1haWx8fG4udXNlci51c2VybmFtZSkpLHQudGltZXN0YW1wPW4udGltZXN0YW1wfHxSKCksbi5hYm5vcm1hbF9tZWNoYW5pc20mJih0LmFibm9ybWFsX21lY2hhbmlzbT1uLmFibm9ybWFsX21lY2hhbmlzbSksbi5pZ25vcmVEdXJhdGlvbiYmKHQuaWdub3JlRHVyYXRpb249bi5pZ25vcmVEdXJhdGlvbiksbi5zaWQmJih0LnNpZD0zMj09PW4uc2lkLmxlbmd0aD9uLnNpZDpZKCkpLHZvaWQgMCE9PW4uaW5pdCYmKHQuaW5pdD1uLmluaXQpLCF0LmRpZCYmbi5kaWQmJih0LmRpZD1gJHtuLmRpZH1gKSwibnVtYmVyIj09dHlwZW9mIG4uc3RhcnRlZCYmKHQuc3RhcnRlZD1uLnN0YXJ0ZWQpLHQuaWdub3JlRHVyYXRpb24pdC5kdXJhdGlvbj12b2lkIDA7ZWxzZSBpZigibnVtYmVyIj09dHlwZW9mIG4uZHVyYXRpb24pdC5kdXJhdGlvbj1uLmR1cmF0aW9uO2Vsc2V7Y29uc3Qgbj10LnRpbWVzdGFtcC10LnN0YXJ0ZWQ7dC5kdXJhdGlvbj1uPj0wP246MH1uLnJlbGVhc2UmJih0LnJlbGVhc2U9bi5yZWxlYXNlKSxuLmVudmlyb25tZW50JiYodC5lbnZpcm9ubWVudD1uLmVudmlyb25tZW50KSwhdC5pcEFkZHJlc3MmJm4uaXBBZGRyZXNzJiYodC5pcEFkZHJlc3M9bi5pcEFkZHJlc3MpLCF0LnVzZXJBZ2VudCYmbi51c2VyQWdlbnQmJih0LnVzZXJBZ2VudD1uLnVzZXJBZ2VudCksIm51bWJlciI9PXR5cGVvZiBuLmVycm9ycyYmKHQuZXJyb3JzPW4uZXJyb3JzKSxuLnN0YXR1cyYmKHQuc3RhdHVzPW4uc3RhdHVzKX1mdW5jdGlvbiBWKCl7cmV0dXJuIFkoKX1mdW5jdGlvbiBaKCl7cmV0dXJuIFkoKS5zdWJzdHJpbmcoMTYpfWZ1bmN0aW9uIHEodCxuLGU9Mil7aWYoIW58fCJvYmplY3QiIT10eXBlb2Ygbnx8ZTw9MClyZXR1cm4gbjtpZih0JiYwPT09T2JqZWN0LmtleXMobikubGVuZ3RoKXJldHVybiB0O2NvbnN0IHI9ey4uLnR9O2Zvcihjb25zdCB0IGluIG4pT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG4sdCkmJihyW3RdPXEoclt0XSxuW3RdLGUtMSkpO3JldHVybiByfWNvbnN0IFE9Il9zZW50cnlTcGFuIjtmdW5jdGlvbiBYKHQsbil7bj9mdW5jdGlvbih0LG4sZSl7dHJ5e09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LG4se3ZhbHVlOmUsd3JpdGFibGU6ITAsY29uZmlndXJhYmxlOiEwfSl9Y2F0Y2goZSl7bCYmdy5sb2coYEZhaWxlZCB0byBhZGQgbm9uLWVudW1lcmFibGUgcHJvcGVydHkgIiR7bn0iIHRvIG9iamVjdGAsdCl9fSh0LFEsbik6ZGVsZXRlIHRbUV19ZnVuY3Rpb24gdHQodCl7cmV0dXJuIHRbUV19Y2xhc3MgbnR7Y29uc3RydWN0b3IoKXt0aGlzLnA9ITEsdGhpcy5sPVtdLHRoaXMubT1bXSx0aGlzLl89W10sdGhpcy52PVtdLHRoaXMuUz17fSx0aGlzLk49e30sdGhpcy5UPXt9LHRoaXMuQz17fSx0aGlzLlI9e30sdGhpcy5rPXt0cmFjZUlkOlYoKSxzYW1wbGVSYW5kOk1hdGgucmFuZG9tKCl9fWNsb25lKCl7Y29uc3QgdD1uZXcgbnQ7cmV0dXJuIHQuXz1bLi4udGhpcy5fXSx0Lk49ey4uLnRoaXMuTn0sdC5UPXsuLi50aGlzLlR9LHQuQz17Li4udGhpcy5DfSx0aGlzLkMuZmxhZ3MmJih0LkMuZmxhZ3M9e3ZhbHVlczpbLi4udGhpcy5DLmZsYWdzLnZhbHVlc119KSx0LlM9dGhpcy5TLHQuaj10aGlzLmosdC5EPXRoaXMuRCx0Lkk9dGhpcy5JLHQuTz10aGlzLk8sdC5tPVsuLi50aGlzLm1dLHQudj1bLi4udGhpcy52XSx0LlI9ey4uLnRoaXMuUn0sdC5rPXsuLi50aGlzLmt9LHQuQT10aGlzLkEsdC5QPXRoaXMuUCxYKHQsdHQodGhpcykpLHR9c2V0Q2xpZW50KHQpe3RoaXMuQT10fXNldExhc3RFdmVudElkKHQpe3RoaXMuUD10fWdldENsaWVudCgpe3JldHVybiB0aGlzLkF9bGFzdEV2ZW50SWQoKXtyZXR1cm4gdGhpcy5QfWFkZFNjb3BlTGlzdGVuZXIodCl7dGhpcy5sLnB1c2godCl9YWRkRXZlbnRQcm9jZXNzb3IodCl7cmV0dXJuIHRoaXMubS5wdXNoKHQpLHRoaXN9c2V0VXNlcih0KXtyZXR1cm4gdGhpcy5TPXR8fHtlbWFpbDp2b2lkIDAsaWQ6dm9pZCAwLGlwX2FkZHJlc3M6dm9pZCAwLHVzZXJuYW1lOnZvaWQgMH0sdGhpcy5EJiZLKHRoaXMuRCx7dXNlcjp0fSksdGhpcy5VKCksdGhpc31nZXRVc2VyKCl7cmV0dXJuIHRoaXMuU31zZXRUYWdzKHQpe3JldHVybiB0aGlzLk49ey4uLnRoaXMuTiwuLi50fSx0aGlzLlUoKSx0aGlzfXNldFRhZyh0LG4pe3JldHVybiB0aGlzLk49ey4uLnRoaXMuTixbdF06bn0sdGhpcy5VKCksdGhpc31zZXRFeHRyYXModCl7cmV0dXJuIHRoaXMuVD17Li4udGhpcy5ULC4uLnR9LHRoaXMuVSgpLHRoaXN9c2V0RXh0cmEodCxuKXtyZXR1cm4gdGhpcy5UPXsuLi50aGlzLlQsW3RdOm59LHRoaXMuVSgpLHRoaXN9c2V0RmluZ2VycHJpbnQodCl7cmV0dXJuIHRoaXMuTz10LHRoaXMuVSgpLHRoaXN9c2V0TGV2ZWwodCl7cmV0dXJuIHRoaXMuaj10LHRoaXMuVSgpLHRoaXN9c2V0VHJhbnNhY3Rpb25OYW1lKHQpe3JldHVybiB0aGlzLkk9dCx0aGlzLlUoKSx0aGlzfXNldENvbnRleHQodCxuKXtyZXR1cm4gbnVsbD09PW4/ZGVsZXRlIHRoaXMuQ1t0XTp0aGlzLkNbdF09bix0aGlzLlUoKSx0aGlzfXNldFNlc3Npb24odCl7cmV0dXJuIHQ/dGhpcy5EPXQ6ZGVsZXRlIHRoaXMuRCx0aGlzLlUoKSx0aGlzfWdldFNlc3Npb24oKXtyZXR1cm4gdGhpcy5EfXVwZGF0ZSh0KXtpZighdClyZXR1cm4gdGhpcztjb25zdCBuPSJmdW5jdGlvbiI9PXR5cGVvZiB0P3QodGhpcyk6dCxlPW4gaW5zdGFuY2VvZiBudD9uLmdldFNjb3BlRGF0YSgpOkkobik/dDp2b2lkIDAse3RhZ3M6cixleHRyYTpvLHVzZXI6cyxjb250ZXh0czppLGxldmVsOmMsZmluZ2VycHJpbnQ6dT1bXSxwcm9wYWdhdGlvbkNvbnRleHQ6YX09ZXx8e307cmV0dXJuIHRoaXMuTj17Li4udGhpcy5OLC4uLnJ9LHRoaXMuVD17Li4udGhpcy5ULC4uLm99LHRoaXMuQz17Li4udGhpcy5DLC4uLml9LHMmJk9iamVjdC5rZXlzKHMpLmxlbmd0aCYmKHRoaXMuUz1zKSxjJiYodGhpcy5qPWMpLHUubGVuZ3RoJiYodGhpcy5PPXUpLGEmJih0aGlzLms9YSksdGhpc31jbGVhcigpe3JldHVybiB0aGlzLl89W10sdGhpcy5OPXt9LHRoaXMuVD17fSx0aGlzLlM9e30sdGhpcy5DPXt9LHRoaXMuaj12b2lkIDAsdGhpcy5JPXZvaWQgMCx0aGlzLk89dm9pZCAwLHRoaXMuRD12b2lkIDAsWCh0aGlzLHZvaWQgMCksdGhpcy52PVtdLHRoaXMuc2V0UHJvcGFnYXRpb25Db250ZXh0KHt0cmFjZUlkOlYoKSxzYW1wbGVSYW5kOk1hdGgucmFuZG9tKCl9KSx0aGlzLlUoKSx0aGlzfWFkZEJyZWFkY3J1bWIodCxuKXtjb25zdCBlPSJudW1iZXIiPT10eXBlb2Ygbj9uOjEwMDtpZihlPD0wKXJldHVybiB0aGlzO2NvbnN0IHI9e3RpbWVzdGFtcDpDKCksLi4udCxtZXNzYWdlOnQubWVzc2FnZT9MKHQubWVzc2FnZSwyMDQ4KTp0Lm1lc3NhZ2V9O3JldHVybiB0aGlzLl8ucHVzaChyKSx0aGlzLl8ubGVuZ3RoPmUmJih0aGlzLl89dGhpcy5fLnNsaWNlKC1lKSx0aGlzLkE/LnJlY29yZERyb3BwZWRFdmVudCgiYnVmZmVyX292ZXJmbG93IiwibG9nX2l0ZW0iKSksdGhpcy5VKCksdGhpc31nZXRMYXN0QnJlYWRjcnVtYigpe3JldHVybiB0aGlzLl9bdGhpcy5fLmxlbmd0aC0xXX1jbGVhckJyZWFkY3J1bWJzKCl7cmV0dXJuIHRoaXMuXz1bXSx0aGlzLlUoKSx0aGlzfWFkZEF0dGFjaG1lbnQodCl7cmV0dXJuIHRoaXMudi5wdXNoKHQpLHRoaXN9Y2xlYXJBdHRhY2htZW50cygpe3JldHVybiB0aGlzLnY9W10sdGhpc31nZXRTY29wZURhdGEoKXtyZXR1cm57YnJlYWRjcnVtYnM6dGhpcy5fLGF0dGFjaG1lbnRzOnRoaXMudixjb250ZXh0czp0aGlzLkMsdGFnczp0aGlzLk4sZXh0cmE6dGhpcy5ULHVzZXI6dGhpcy5TLGxldmVsOnRoaXMuaixmaW5nZXJwcmludDp0aGlzLk98fFtdLGV2ZW50UHJvY2Vzc29yczp0aGlzLm0scHJvcGFnYXRpb25Db250ZXh0OnRoaXMuayxzZGtQcm9jZXNzaW5nTWV0YWRhdGE6dGhpcy5SLHRyYW5zYWN0aW9uTmFtZTp0aGlzLkksc3Bhbjp0dCh0aGlzKX19c2V0U0RLUHJvY2Vzc2luZ01ldGFkYXRhKHQpe3JldHVybiB0aGlzLlI9cSh0aGlzLlIsdCwyKSx0aGlzfXNldFByb3BhZ2F0aW9uQ29udGV4dCh0KXtyZXR1cm4gdGhpcy5rPXQsdGhpc31nZXRQcm9wYWdhdGlvbkNvbnRleHQoKXtyZXR1cm4gdGhpcy5rfWNhcHR1cmVFeGNlcHRpb24odCxuKXtjb25zdCBlPW4/LmV2ZW50X2lkfHxZKCk7aWYoIXRoaXMuQSlyZXR1cm4gdy53YXJuKCJObyBjbGllbnQgY29uZmlndXJlZCBvbiBzY29wZSAtIHdpbGwgbm90IGNhcHR1cmUgZXhjZXB0aW9uISIpLGU7Y29uc3Qgcj1uZXcgRXJyb3IoIlNlbnRyeSBzeW50aGV0aWNFeGNlcHRpb24iKTtyZXR1cm4gdGhpcy5BLmNhcHR1cmVFeGNlcHRpb24odCx7b3JpZ2luYWxFeGNlcHRpb246dCxzeW50aGV0aWNFeGNlcHRpb246ciwuLi5uLGV2ZW50X2lkOmV9LHRoaXMpLGV9Y2FwdHVyZU1lc3NhZ2UodCxuLGUpe2NvbnN0IHI9ZT8uZXZlbnRfaWR8fFkoKTtpZighdGhpcy5BKXJldHVybiB3Lndhcm4oIk5vIGNsaWVudCBjb25maWd1cmVkIG9uIHNjb3BlIC0gd2lsbCBub3QgY2FwdHVyZSBtZXNzYWdlISIpLHI7Y29uc3Qgbz1uZXcgRXJyb3IodCk7cmV0dXJuIHRoaXMuQS5jYXB0dXJlTWVzc2FnZSh0LG4se29yaWdpbmFsRXhjZXB0aW9uOnQsc3ludGhldGljRXhjZXB0aW9uOm8sLi4uZSxldmVudF9pZDpyfSx0aGlzKSxyfWNhcHR1cmVFdmVudCh0LG4pe2NvbnN0IGU9bj8uZXZlbnRfaWR8fFkoKTtyZXR1cm4gdGhpcy5BPyh0aGlzLkEuY2FwdHVyZUV2ZW50KHQsey4uLm4sZXZlbnRfaWQ6ZX0sdGhpcyksZSk6KHcud2FybigiTm8gY2xpZW50IGNvbmZpZ3VyZWQgb24gc2NvcGUgLSB3aWxsIG5vdCBjYXB0dXJlIGV2ZW50ISIpLGUpfVUoKXt0aGlzLnB8fCh0aGlzLnA9ITAsdGhpcy5sLmZvckVhY2goKHQ9Pnt0KHRoaXMpfSkpLHRoaXMucD0hMSl9fWNsYXNzIGV0e2NvbnN0cnVjdG9yKHQsbil7bGV0IGUscjtlPXR8fG5ldyBudCxyPW58fG5ldyBudCx0aGlzLk09W3tzY29wZTplfV0sdGhpcy5MPXJ9d2l0aFNjb3BlKHQpe2NvbnN0IG49dGhpcy5CKCk7bGV0IGU7dHJ5e2U9dChuKX1jYXRjaCh0KXt0aHJvdyB0aGlzLkcoKSx0fXJldHVybiBPKGUpP2UudGhlbigodD0+KHRoaXMuRygpLHQpKSwodD0+e3Rocm93IHRoaXMuRygpLHR9KSk6KHRoaXMuRygpLGUpfWdldENsaWVudCgpe3JldHVybiB0aGlzLmdldFN0YWNrVG9wKCkuY2xpZW50fWdldFNjb3BlKCl7cmV0dXJuIHRoaXMuZ2V0U3RhY2tUb3AoKS5zY29wZX1nZXRJc29sYXRpb25TY29wZSgpe3JldHVybiB0aGlzLkx9Z2V0U3RhY2tUb3AoKXtyZXR1cm4gdGhpcy5NW3RoaXMuTS5sZW5ndGgtMV19Qigpe2NvbnN0IHQ9dGhpcy5nZXRTY29wZSgpLmNsb25lKCk7cmV0dXJuIHRoaXMuTS5wdXNoKHtjbGllbnQ6dGhpcy5nZXRDbGllbnQoKSxzY29wZTp0fSksdH1HKCl7cmV0dXJuISh0aGlzLk0ubGVuZ3RoPD0xKSYmISF0aGlzLk0ucG9wKCl9fWZ1bmN0aW9uIHJ0KCl7Y29uc3QgdD1nKG0oKSk7cmV0dXJuIHQuc3RhY2s9dC5zdGFja3x8bmV3IGV0KHkoImRlZmF1bHRDdXJyZW50U2NvcGUiLCgoKT0+bmV3IG50KSkseSgiZGVmYXVsdElzb2xhdGlvblNjb3BlIiwoKCk9Pm5ldyBudCkpKX1mdW5jdGlvbiBvdCh0KXtyZXR1cm4gcnQoKS53aXRoU2NvcGUodCl9ZnVuY3Rpb24gc3QodCxuKXtjb25zdCBlPXJ0KCk7cmV0dXJuIGUud2l0aFNjb3BlKCgoKT0+KGUuZ2V0U3RhY2tUb3AoKS5zY29wZT10LG4odCkpKSl9ZnVuY3Rpb24gaXQodCl7cmV0dXJuIHJ0KCkud2l0aFNjb3BlKCgoKT0+dChydCgpLmdldElzb2xhdGlvblNjb3BlKCkpKSl9ZnVuY3Rpb24gY3QodCl7Y29uc3Qgbj1nKHQpO3JldHVybiBuLmFjcz9uLmFjczp7d2l0aElzb2xhdGlvblNjb3BlOml0LHdpdGhTY29wZTpvdCx3aXRoU2V0U2NvcGU6c3Qsd2l0aFNldElzb2xhdGlvblNjb3BlOih0LG4pPT5pdChuKSxnZXRDdXJyZW50U2NvcGU6KCk9PnJ0KCkuZ2V0U2NvcGUoKSxnZXRJc29sYXRpb25TY29wZTooKT0+cnQoKS5nZXRJc29sYXRpb25TY29wZSgpfX1mdW5jdGlvbiB1dCgpe3JldHVybiBjdChtKCkpLmdldEN1cnJlbnRTY29wZSgpLmdldENsaWVudCgpfWNvbnN0IGF0PSJzZW50cnkuc291cmNlIixmdD0ic2VudHJ5LnNhbXBsZV9yYXRlIixodD0ic2VudHJ5Lm9wIixwdD0ic2VudHJ5Lm9yaWdpbiIsbHQ9MCxkdD0xLG10PSJfc2VudHJ5U2NvcGUiLGd0PSJfc2VudHJ5SXNvbGF0aW9uU2NvcGUiO2Z1bmN0aW9uIHl0KHQpe3JldHVybntzY29wZTp0W210XSxpc29sYXRpb25TY29wZTp0W2d0XX19Y29uc3QgYnQ9InNlbnRyeS0iLF90PS9ec2VudHJ5LS87ZnVuY3Rpb24gdnQodCl7Y29uc3Qgbj1mdW5jdGlvbih0KXtpZighdHx8IUQodCkmJiFBcnJheS5pc0FycmF5KHQpKXJldHVybjtpZihBcnJheS5pc0FycmF5KHQpKXJldHVybiB0LnJlZHVjZSgoKHQsbik9Pntjb25zdCBlPXd0KG4pO3JldHVybiBPYmplY3QuZW50cmllcyhlKS5mb3JFYWNoKCgoW24sZV0pPT57dFtuXT1lfSkpLHR9KSx7fSk7cmV0dXJuIHd0KHQpfSh0KTtpZighbilyZXR1cm47Y29uc3QgZT1PYmplY3QuZW50cmllcyhuKS5yZWR1Y2UoKCh0LFtuLGVdKT0+e2lmKG4ubWF0Y2goX3QpKXt0W24uc2xpY2UoYnQubGVuZ3RoKV09ZX1yZXR1cm4gdH0pLHt9KTtyZXR1cm4gT2JqZWN0LmtleXMoZSkubGVuZ3RoPjA/ZTp2b2lkIDB9ZnVuY3Rpb24gd3QodCl7cmV0dXJuIHQuc3BsaXQoIiwiKS5tYXAoKHQ9PnQuc3BsaXQoIj0iKS5tYXAoKHQ9PmRlY29kZVVSSUNvbXBvbmVudCh0LnRyaW0oKSkpKSkpLnJlZHVjZSgoKHQsW24sZV0pPT4obiYmZSYmKHRbbl09ZSksdCkpLHt9KX1jb25zdCBTdD0xO2Z1bmN0aW9uICR0KHQpe2NvbnN0e3NwYW5JZDpuLHRyYWNlSWQ6ZSxpc1JlbW90ZTpyfT10LnNwYW5Db250ZXh0KCksbz1yP246VHQodCkucGFyZW50X3NwYW5faWQscz15dCh0KS5zY29wZTtyZXR1cm57cGFyZW50X3NwYW5faWQ6byxzcGFuX2lkOnI/cz8uZ2V0UHJvcGFnYXRpb25Db250ZXh0KCkucHJvcGFnYXRpb25TcGFuSWR8fFooKTpuLHRyYWNlX2lkOmV9fWZ1bmN0aW9uIEV0KHQpe3JldHVybiB0JiZ0Lmxlbmd0aD4wP3QubWFwKCgoe2NvbnRleHQ6e3NwYW5JZDp0LHRyYWNlSWQ6bix0cmFjZUZsYWdzOmUsLi4ucn0sYXR0cmlidXRlczpvfSk9Pih7c3Bhbl9pZDp0LHRyYWNlX2lkOm4sc2FtcGxlZDplPT09U3QsYXR0cmlidXRlczpvLC4uLnJ9KSkpOnZvaWQgMH1mdW5jdGlvbiB4dCh0KXtyZXR1cm4ibnVtYmVyIj09dHlwZW9mIHQ/TnQodCk6QXJyYXkuaXNBcnJheSh0KT90WzBdK3RbMV0vMWU5OnQgaW5zdGFuY2VvZiBEYXRlP050KHQuZ2V0VGltZSgpKTpSKCl9ZnVuY3Rpb24gTnQodCl7cmV0dXJuIHQ+OTk5OTk5OTk5OT90LzFlMzp0fWZ1bmN0aW9uIFR0KHQpe2lmKGZ1bmN0aW9uKHQpe3JldHVybiJmdW5jdGlvbiI9PXR5cGVvZiB0LmdldFNwYW5KU09OfSh0KSlyZXR1cm4gdC5nZXRTcGFuSlNPTigpO2NvbnN0e3NwYW5JZDpuLHRyYWNlSWQ6ZX09dC5zcGFuQ29udGV4dCgpO2lmKGZ1bmN0aW9uKHQpe2NvbnN0IG49dDtyZXR1cm4hIShuLmF0dHJpYnV0ZXMmJm4uc3RhcnRUaW1lJiZuLm5hbWUmJm4uZW5kVGltZSYmbi5zdGF0dXMpfSh0KSl7Y29uc3R7YXR0cmlidXRlczpyLHN0YXJ0VGltZTpvLG5hbWU6cyxlbmRUaW1lOmkscGFyZW50U3BhbklkOmMsc3RhdHVzOnUsbGlua3M6YX09dDtyZXR1cm57c3Bhbl9pZDpuLHRyYWNlX2lkOmUsZGF0YTpyLGRlc2NyaXB0aW9uOnMscGFyZW50X3NwYW5faWQ6YyxzdGFydF90aW1lc3RhbXA6eHQobyksdGltZXN0YW1wOnh0KGkpfHx2b2lkIDAsc3RhdHVzOkN0KHUpLG9wOnJbaHRdLG9yaWdpbjpyW3B0XSxsaW5rczpFdChhKX19cmV0dXJue3NwYW5faWQ6bix0cmFjZV9pZDplLHN0YXJ0X3RpbWVzdGFtcDowLGRhdGE6e319fWZ1bmN0aW9uIEN0KHQpe2lmKHQmJnQuY29kZSE9PWx0KXJldHVybiB0LmNvZGU9PT1kdD8ib2siOnQubWVzc2FnZXx8InVua25vd25fZXJyb3IifWNvbnN0IFJ0PSJfc2VudHJ5Um9vdFNwYW4iO2Z1bmN0aW9uIGt0KHQpe3JldHVybiB0W1J0XXx8dH1jb25zdCBqdD0icHJvZHVjdGlvbiIsRHQ9Il9mcm96ZW5Ec2MiO2Z1bmN0aW9uIEl0KHQpe2NvbnN0IG49dXQoKTtpZighbilyZXR1cm57fTtjb25zdCBlPWt0KHQpLHI9VHQoZSksbz1yLmRhdGEscz1lLnNwYW5Db250ZXh0KCkudHJhY2VTdGF0ZSxpPXM/LmdldCgic2VudHJ5LnNhbXBsZV9yYXRlIik/P29bZnRdO2Z1bmN0aW9uIGModCl7cmV0dXJuIm51bWJlciIhPXR5cGVvZiBpJiYic3RyaW5nIiE9dHlwZW9mIGl8fCh0LnNhbXBsZV9yYXRlPWAke2l9YCksdH1jb25zdCB1PWVbRHRdO2lmKHUpcmV0dXJuIGModSk7Y29uc3QgYT1zPy5nZXQoInNlbnRyeS5kc2MiKSxmPWEmJnZ0KGEpO2lmKGYpcmV0dXJuIGMoZik7Y29uc3QgaD1mdW5jdGlvbih0LG4pe2NvbnN0IGU9bi5nZXRPcHRpb25zKCkse3B1YmxpY0tleTpyfT1uLmdldERzbigpfHx7fSxvPXtlbnZpcm9ubWVudDplLmVudmlyb25tZW50fHxqdCxyZWxlYXNlOmUucmVsZWFzZSxwdWJsaWNfa2V5OnIsdHJhY2VfaWQ6dH07cmV0dXJuIG4uZW1pdCgiY3JlYXRlRHNjIixvKSxvfSh0LnNwYW5Db250ZXh0KCkudHJhY2VJZCxuKSxwPW9bYXRdLGw9ci5kZXNjcmlwdGlvbjtyZXR1cm4idXJsIiE9PXAmJmwmJihoLnRyYW5zYWN0aW9uPWwpLGZ1bmN0aW9uKHQpe2lmKCJib29sZWFuIj09dHlwZW9mIF9fU0VOVFJZX1RSQUNJTkdfXyYmIV9fU0VOVFJZX1RSQUNJTkdfXylyZXR1cm4hMTtjb25zdCBuPXR8fHV0KCk/LmdldE9wdGlvbnMoKTtyZXR1cm4hKCFufHxudWxsPT1uLnRyYWNlc1NhbXBsZVJhdGUmJiFuLnRyYWNlc1NhbXBsZXIpfSgpJiYoaC5zYW1wbGVkPVN0cmluZyhmdW5jdGlvbih0KXtjb25zdHt0cmFjZUZsYWdzOm59PXQuc3BhbkNvbnRleHQoKTtyZXR1cm4gbj09PVN0fShlKSksaC5zYW1wbGVfcmFuZD1zPy5nZXQoInNlbnRyeS5zYW1wbGVfcmFuZCIpPz95dChlKS5zY29wZT8uZ2V0UHJvcGFnYXRpb25Db250ZXh0KCkuc2FtcGxlUmFuZC50b1N0cmluZygpKSxjKGgpLG4uZW1pdCgiY3JlYXRlRHNjIixoLGUpLGh9ZnVuY3Rpb24gT3QodCxuPSExKXtjb25zdHtob3N0OmUscGF0aDpyLHBhc3M6byxwb3J0OnMscHJvamVjdElkOmkscHJvdG9jb2w6YyxwdWJsaWNLZXk6dX09dDtyZXR1cm5gJHtjfTovLyR7dX0ke24mJm8/YDoke299YDoiIn1AJHtlfSR7cz9gOiR7c31gOiIifS8ke3I/YCR7cn0vYDpyfSR7aX1gfWZ1bmN0aW9uIEF0KHQsbj0xMDAsZT0xLzApe3RyeXtyZXR1cm4gUHQoIiIsdCxuLGUpfWNhdGNoKHQpe3JldHVybntFUlJPUjpgKipub24tc2VyaWFsaXphYmxlKiogKCR7dH0pYH19fWZ1bmN0aW9uIFB0KHQsbixlPTEvMCxyPTEvMCxvPWZ1bmN0aW9uKCl7Y29uc3QgdD1uZXcgV2Vha1NldDtmdW5jdGlvbiBuKG4pe3JldHVybiEhdC5oYXMobil8fCh0LmFkZChuKSwhMSl9ZnVuY3Rpb24gZShuKXt0LmRlbGV0ZShuKX1yZXR1cm5bbixlXX0oKSl7Y29uc3RbcyxpXT1vO2lmKG51bGw9PW58fFsiYm9vbGVhbiIsInN0cmluZyJdLmluY2x1ZGVzKHR5cGVvZiBuKXx8Im51bWJlciI9PXR5cGVvZiBuJiZOdW1iZXIuaXNGaW5pdGUobikpcmV0dXJuIG47Y29uc3QgYz1mdW5jdGlvbih0LG4pe3RyeXtpZigiZG9tYWluIj09PXQmJm4mJiJvYmplY3QiPT10eXBlb2YgbiYmbi5KKXJldHVybiJbRG9tYWluXSI7aWYoImRvbWFpbkVtaXR0ZXIiPT09dClyZXR1cm4iW0RvbWFpbkVtaXR0ZXJdIjtpZigidW5kZWZpbmVkIiE9dHlwZW9mIGdsb2JhbCYmbj09PWdsb2JhbClyZXR1cm4iW0dsb2JhbF0iO2lmKCJ1bmRlZmluZWQiIT10eXBlb2Ygd2luZG93JiZuPT09d2luZG93KXJldHVybiJbV2luZG93XSI7aWYoInVuZGVmaW5lZCIhPXR5cGVvZiBkb2N1bWVudCYmbj09PWRvY3VtZW50KXJldHVybiJbRG9jdW1lbnRdIjtpZigib2JqZWN0Ij09dHlwZW9mKGU9bikmJm51bGwhPT1lJiYoZS5fX2lzVnVlfHxlLlkpKXJldHVybiJbVnVlVmlld01vZGVsXSI7aWYoZnVuY3Rpb24odCl7cmV0dXJuIEkodCkmJiJuYXRpdmVFdmVudCJpbiB0JiYicHJldmVudERlZmF1bHQiaW4gdCYmInN0b3BQcm9wYWdhdGlvbiJpbiB0fShuKSlyZXR1cm4iW1N5bnRoZXRpY0V2ZW50XSI7aWYoIm51bWJlciI9PXR5cGVvZiBuJiYhTnVtYmVyLmlzRmluaXRlKG4pKXJldHVybmBbJHtufV1gO2lmKCJmdW5jdGlvbiI9PXR5cGVvZiBuKXJldHVybmBbRnVuY3Rpb246ICR7ZnVuY3Rpb24odCl7dHJ5e3JldHVybiB0JiYiZnVuY3Rpb24iPT10eXBlb2YgdCYmdC5uYW1lfHxOfWNhdGNoKHQpe3JldHVybiBOfX0obil9XWA7aWYoInN5bWJvbCI9PXR5cGVvZiBuKXJldHVybmBbJHtTdHJpbmcobil9XWA7aWYoImJpZ2ludCI9PXR5cGVvZiBuKXJldHVybmBbQmlnSW50OiAke1N0cmluZyhuKX1dYDtjb25zdCByPWZ1bmN0aW9uKHQpe2NvbnN0IG49T2JqZWN0LmdldFByb3RvdHlwZU9mKHQpO3JldHVybiBuPy5jb25zdHJ1Y3Rvcj9uLmNvbnN0cnVjdG9yLm5hbWU6Im51bGwgcHJvdG90eXBlIn0obik7cmV0dXJuL15IVE1MKFx3KilFbGVtZW50JC8udGVzdChyKT9gW0hUTUxFbGVtZW50OiAke3J9XWA6YFtvYmplY3QgJHtyfV1gfWNhdGNoKHQpe3JldHVybmAqKm5vbi1zZXJpYWxpemFibGUqKiAoJHt0fSlgfXZhciBlfSh0LG4pO2lmKCFjLnN0YXJ0c1dpdGgoIltvYmplY3QgIikpcmV0dXJuIGM7aWYobi5fX3NlbnRyeV9za2lwX25vcm1hbGl6YXRpb25fXylyZXR1cm4gbjtjb25zdCB1PSJudW1iZXIiPT10eXBlb2Ygbi5fX3NlbnRyeV9vdmVycmlkZV9ub3JtYWxpemF0aW9uX2RlcHRoX18/bi5fX3NlbnRyeV9vdmVycmlkZV9ub3JtYWxpemF0aW9uX2RlcHRoX186ZTtpZigwPT09dSlyZXR1cm4gYy5yZXBsYWNlKCJvYmplY3QgIiwiIik7aWYocyhuKSlyZXR1cm4iW0NpcmN1bGFyIH5dIjtjb25zdCBhPW47aWYoYSYmImZ1bmN0aW9uIj09dHlwZW9mIGEudG9KU09OKXRyeXtyZXR1cm4gUHQoIiIsYS50b0pTT04oKSx1LTEscixvKX1jYXRjaCh0KXt9Y29uc3QgZj1BcnJheS5pc0FycmF5KG4pP1tdOnt9O2xldCBoPTA7Y29uc3QgcD1CKG4pO2Zvcihjb25zdCB0IGluIHApe2lmKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocCx0KSljb250aW51ZTtpZihoPj1yKXtmW3RdPSJbTWF4UHJvcGVydGllcyB+XSI7YnJlYWt9Y29uc3Qgbj1wW3RdO2ZbdF09UHQodCxuLHUtMSxyLG8pLGgrK31yZXR1cm4gaShuKSxmfWZ1bmN0aW9uIFV0KHQsbil7Y29uc3QgZT1uLnJlcGxhY2UoL1xcL2csIi8iKS5yZXBsYWNlKC9bfFxce30oKVtcXV4kKyo/Ll0vZywiXFwkJiIpO2xldCByPXQ7dHJ5e3I9ZGVjb2RlVVJJKHQpfWNhdGNoKHQpe31yZXR1cm4gci5yZXBsYWNlKC9cXC9nLCIvIikucmVwbGFjZSgvd2VicGFjazpcLz8vZywiIikucmVwbGFjZShuZXcgUmVnRXhwKGAoZmlsZTovLyk/Lyoke2V9LypgLCJpZyIpLCJhcHA6Ly8vIil9ZnVuY3Rpb24gTXQodCxuPVtdKXtyZXR1cm5bdCxuXX1mdW5jdGlvbiBMdCh0LG4pe2NvbnN0IGU9dFsxXTtmb3IoY29uc3QgdCBvZiBlKXtpZihuKHQsdFswXS50eXBlKSlyZXR1cm4hMH1yZXR1cm4hMX1mdW5jdGlvbiBCdCh0KXtjb25zdCBuPWcocCk7cmV0dXJuIG4uZW5jb2RlUG9seWZpbGw/bi5lbmNvZGVQb2x5ZmlsbCh0KToobmV3IFRleHRFbmNvZGVyKS5lbmNvZGUodCl9ZnVuY3Rpb24gR3QodCl7Y29uc3RbbixlXT10O2xldCByPUpTT04uc3RyaW5naWZ5KG4pO2Z1bmN0aW9uIG8odCl7InN0cmluZyI9PXR5cGVvZiByP3I9InN0cmluZyI9PXR5cGVvZiB0P3IrdDpbQnQociksdF06ci5wdXNoKCJzdHJpbmciPT10eXBlb2YgdD9CdCh0KTp0KX1mb3IoY29uc3QgdCBvZiBlKXtjb25zdFtuLGVdPXQ7aWYobyhgXG4ke0pTT04uc3RyaW5naWZ5KG4pfVxuYCksInN0cmluZyI9PXR5cGVvZiBlfHxlIGluc3RhbmNlb2YgVWludDhBcnJheSlvKGUpO2Vsc2V7bGV0IHQ7dHJ5e3Q9SlNPTi5zdHJpbmdpZnkoZSl9Y2F0Y2gobil7dD1KU09OLnN0cmluZ2lmeShBdChlKSl9byh0KX19cmV0dXJuInN0cmluZyI9PXR5cGVvZiByP3I6ZnVuY3Rpb24odCl7Y29uc3Qgbj10LnJlZHVjZSgoKHQsbik9PnQrbi5sZW5ndGgpLDApLGU9bmV3IFVpbnQ4QXJyYXkobik7bGV0IHI9MDtmb3IoY29uc3QgbiBvZiB0KWUuc2V0KG4scikscis9bi5sZW5ndGg7cmV0dXJuIGV9KHIpfWNvbnN0IEp0PXtzZXNzaW9uOiJzZXNzaW9uIixzZXNzaW9uczoic2Vzc2lvbiIsYXR0YWNobWVudDoiYXR0YWNobWVudCIsdHJhbnNhY3Rpb246InRyYW5zYWN0aW9uIixldmVudDoiZXJyb3IiLGNsaWVudF9yZXBvcnQ6ImludGVybmFsIix1c2VyX3JlcG9ydDoiZGVmYXVsdCIscHJvZmlsZToicHJvZmlsZSIscHJvZmlsZV9jaHVuazoicHJvZmlsZSIscmVwbGF5X2V2ZW50OiJyZXBsYXkiLHJlcGxheV9yZWNvcmRpbmc6InJlcGxheSIsY2hlY2tfaW46Im1vbml0b3IiLGZlZWRiYWNrOiJmZWVkYmFjayIsc3Bhbjoic3BhbiIscmF3X3NlY3VyaXR5OiJzZWN1cml0eSIsb3RlbF9sb2c6ImxvZ19pdGVtIn07ZnVuY3Rpb24gWXQodCl7aWYoIXQ/LnNkaylyZXR1cm47Y29uc3R7bmFtZTpuLHZlcnNpb246ZX09dC5zZGs7cmV0dXJue25hbWU6bix2ZXJzaW9uOmV9fWZ1bmN0aW9uIHp0KHQsbixlLHIpe2NvbnN0IG89WXQoZSkscz10LnR5cGUmJiJyZXBsYXlfZXZlbnQiIT09dC50eXBlP3QudHlwZToiZXZlbnQiOyFmdW5jdGlvbih0LG4pe24mJih0LnNkaz10LnNka3x8e30sdC5zZGsubmFtZT10LnNkay5uYW1lfHxuLm5hbWUsdC5zZGsudmVyc2lvbj10LnNkay52ZXJzaW9ufHxuLnZlcnNpb24sdC5zZGsuaW50ZWdyYXRpb25zPVsuLi50LnNkay5pbnRlZ3JhdGlvbnN8fFtdLC4uLm4uaW50ZWdyYXRpb25zfHxbXV0sdC5zZGsucGFja2FnZXM9Wy4uLnQuc2RrLnBhY2thZ2VzfHxbXSwuLi5uLnBhY2thZ2VzfHxbXV0pfSh0LGU/LnNkayk7Y29uc3QgaT1mdW5jdGlvbih0LG4sZSxyKXtjb25zdCBvPXQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhPy5keW5hbWljU2FtcGxpbmdDb250ZXh0O3JldHVybntldmVudF9pZDp0LmV2ZW50X2lkLHNlbnRfYXQ6KG5ldyBEYXRlKS50b0lTT1N0cmluZygpLC4uLm4mJntzZGs6bn0sLi4uISFlJiZyJiZ7ZHNuOk90KHIpfSwuLi5vJiZ7dHJhY2U6b319fSh0LG8scixuKTtkZWxldGUgdC5zZGtQcm9jZXNzaW5nTWV0YWRhdGE7cmV0dXJuIE10KGksW1t7dHlwZTpzfSx0XV0pfWNvbnN0IEh0PSJfX1NFTlRSWV9TVVBQUkVTU19UUkFDSU5HX18iO2Z1bmN0aW9uIEZ0KHQpe2NvbnN0IG49Y3QobSgpKTtyZXR1cm4gbi5zdXBwcmVzc1RyYWNpbmc/bi5zdXBwcmVzc1RyYWNpbmcodCk6ZnVuY3Rpb24oLi4udCl7Y29uc3Qgbj1jdChtKCkpO2lmKDI9PT10Lmxlbmd0aCl7Y29uc3RbZSxyXT10O3JldHVybiBlP24ud2l0aFNldFNjb3BlKGUscik6bi53aXRoU2NvcGUocil9cmV0dXJuIG4ud2l0aFNjb3BlKHRbMF0pfSgobj0+KG4uc2V0U0RLUHJvY2Vzc2luZ01ldGFkYXRhKHtbSHRdOiEwfSksdCgpKSkpfWZ1bmN0aW9uIFd0KHQsbil7Y29uc3R7ZmluZ2VycHJpbnQ6ZSxzcGFuOnIsYnJlYWRjcnVtYnM6byxzZGtQcm9jZXNzaW5nTWV0YWRhdGE6c309bjshZnVuY3Rpb24odCxuKXtjb25zdHtleHRyYTplLHRhZ3M6cix1c2VyOm8sY29udGV4dHM6cyxsZXZlbDppLHRyYW5zYWN0aW9uTmFtZTpjfT1uO09iamVjdC5rZXlzKGUpLmxlbmd0aCYmKHQuZXh0cmE9ey4uLmUsLi4udC5leHRyYX0pO09iamVjdC5rZXlzKHIpLmxlbmd0aCYmKHQudGFncz17Li4uciwuLi50LnRhZ3N9KTtPYmplY3Qua2V5cyhvKS5sZW5ndGgmJih0LnVzZXI9ey4uLm8sLi4udC51c2VyfSk7T2JqZWN0LmtleXMocykubGVuZ3RoJiYodC5jb250ZXh0cz17Li4ucywuLi50LmNvbnRleHRzfSk7aSYmKHQubGV2ZWw9aSk7YyYmInRyYW5zYWN0aW9uIiE9PXQudHlwZSYmKHQudHJhbnNhY3Rpb249Yyl9KHQsbiksciYmZnVuY3Rpb24odCxuKXt0LmNvbnRleHRzPXt0cmFjZTokdChuKSwuLi50LmNvbnRleHRzfSx0LnNka1Byb2Nlc3NpbmdNZXRhZGF0YT17ZHluYW1pY1NhbXBsaW5nQ29udGV4dDpJdChuKSwuLi50LnNka1Byb2Nlc3NpbmdNZXRhZGF0YX07Y29uc3QgZT1rdChuKSxyPVR0KGUpLmRlc2NyaXB0aW9uO3ImJiF0LnRyYW5zYWN0aW9uJiYidHJhbnNhY3Rpb24iPT09dC50eXBlJiYodC50cmFuc2FjdGlvbj1yKX0odCxyKSxmdW5jdGlvbih0LG4pe3QuZmluZ2VycHJpbnQ9dC5maW5nZXJwcmludD9BcnJheS5pc0FycmF5KHQuZmluZ2VycHJpbnQpP3QuZmluZ2VycHJpbnQ6W3QuZmluZ2VycHJpbnRdOltdLG4mJih0LmZpbmdlcnByaW50PXQuZmluZ2VycHJpbnQuY29uY2F0KG4pKTt0LmZpbmdlcnByaW50Lmxlbmd0aHx8ZGVsZXRlIHQuZmluZ2VycHJpbnR9KHQsZSksZnVuY3Rpb24odCxuKXtjb25zdCBlPVsuLi50LmJyZWFkY3J1bWJzfHxbXSwuLi5uXTt0LmJyZWFkY3J1bWJzPWUubGVuZ3RoP2U6dm9pZCAwfSh0LG8pLGZ1bmN0aW9uKHQsbil7dC5zZGtQcm9jZXNzaW5nTWV0YWRhdGE9ey4uLnQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhLC4uLm59fSh0LHMpfWNvbnN0IEt0PSI3Ijtjb25zdCBWdD1TeW1ib2wuZm9yKCJTZW50cnlCdWZmZXJGdWxsRXJyb3IiKTtmdW5jdGlvbiBadCh0KXtjb25zdCBuPVtdO2Z1bmN0aW9uIGUodCl7cmV0dXJuIG4uc3BsaWNlKG4uaW5kZXhPZih0KSwxKVswXXx8UHJvbWlzZS5yZXNvbHZlKHZvaWQgMCl9cmV0dXJueyQ6bixhZGQ6ZnVuY3Rpb24ocil7aWYoISh2b2lkIDA9PT10fHxuLmxlbmd0aDx0KSlyZXR1cm4gbz1WdCxuZXcgRigoKHQsbik9PntuKG8pfSkpO3ZhciBvO2NvbnN0IHM9cigpO3JldHVybi0xPT09bi5pbmRleE9mKHMpJiZuLnB1c2gocykscy50aGVuKCgoKT0+ZShzKSkpLnRoZW4obnVsbCwoKCk9PmUocykudGhlbihudWxsLCgoKT0+e30pKSkpLHN9LGRyYWluOmZ1bmN0aW9uKHQpe3JldHVybiBuZXcgRigoKGUscik9PntsZXQgbz1uLmxlbmd0aDtpZighbylyZXR1cm4gZSghMCk7Y29uc3Qgcz1zZXRUaW1lb3V0KCgoKT0+e3QmJnQ+MCYmZSghMSl9KSx0KTtuLmZvckVhY2goKHQ9PntIKHQpLnRoZW4oKCgpPT57LS1vfHwoY2xlYXJUaW1lb3V0KHMpLGUoITApKX0pLHIpfSkpfSkpfX19Y29uc3QgcXQ9NmU0O2Z1bmN0aW9uIFF0KHQse3N0YXR1c0NvZGU6bixoZWFkZXJzOmV9LHI9RGF0ZS5ub3coKSl7Y29uc3Qgbz17Li4udH0scz1lPy5bIngtc2VudHJ5LXJhdGUtbGltaXRzIl0saT1lPy5bInJldHJ5LWFmdGVyIl07aWYocylmb3IoY29uc3QgdCBvZiBzLnRyaW0oKS5zcGxpdCgiLCIpKXtjb25zdFtuLGUsLCxzXT10LnNwbGl0KCI6Iiw1KSxpPXBhcnNlSW50KG4sMTApLGM9MWUzKihpc05hTihpKT82MDppKTtpZihlKWZvcihjb25zdCB0IG9mIGUuc3BsaXQoIjsiKSkibWV0cmljX2J1Y2tldCI9PT10JiZzJiYhcy5zcGxpdCgiOyIpLmluY2x1ZGVzKCJjdXN0b20iKXx8KG9bdF09citjKTtlbHNlIG8uYWxsPXIrY31lbHNlIGk/by5hbGw9citmdW5jdGlvbih0LG49RGF0ZS5ub3coKSl7Y29uc3QgZT1wYXJzZUludChgJHt0fWAsMTApO2lmKCFpc05hTihlKSlyZXR1cm4gMWUzKmU7Y29uc3Qgcj1EYXRlLnBhcnNlKGAke3R9YCk7cmV0dXJuIGlzTmFOKHIpP3F0OnItbn0oaSxyKTo0Mjk9PT1uJiYoby5hbGw9cis2ZTQpO3JldHVybiBvfWNvbnN0IFh0PTY0O2Z1bmN0aW9uIHRuKHQsbixlPVp0KHQuYnVmZmVyU2l6ZXx8WHQpKXtsZXQgcj17fTtyZXR1cm57c2VuZDpmdW5jdGlvbih0KXtjb25zdCBvPVtdO2lmKEx0KHQsKCh0LG4pPT57Y29uc3QgZT1mdW5jdGlvbih0KXtyZXR1cm4gSnRbdF19KG4pOyhmdW5jdGlvbih0LG4sZT1EYXRlLm5vdygpKXtyZXR1cm4gZnVuY3Rpb24odCxuKXtyZXR1cm4gdFtuXXx8dC5hbGx8fDB9KHQsbik+ZX0pKHIsZSl8fG8ucHVzaCh0KX0pKSwwPT09by5sZW5ndGgpcmV0dXJuIEgoe30pO2NvbnN0IHM9TXQodFswXSxvKSxpPXQ9PntMdChzLCgodCxuKT0+e30pKX07cmV0dXJuIGUuYWRkKCgoKT0+bih7Ym9keTpHdChzKX0pLnRoZW4oKHQ9Pih2b2lkIDAhPT10LnN0YXR1c0NvZGUmJih0LnN0YXR1c0NvZGU8MjAwfHx0LnN0YXR1c0NvZGU+PTMwMCkmJmgmJncud2FybihgU2VudHJ5IHJlc3BvbmRlZCB3aXRoIHN0YXR1cyBjb2RlICR7dC5zdGF0dXNDb2RlfSB0byBzZW50IGV2ZW50LmApLHI9UXQocix0KSx0KSksKHQ9Pnt0aHJvdyBpKCksaCYmdy5lcnJvcigiRW5jb3VudGVyZWQgZXJyb3IgcnVubmluZyB0cmFuc3BvcnQgcmVxdWVzdDoiLHQpLHR9KSkpKS50aGVuKCh0PT50KSwodD0+e2lmKHQ9PT1WdClyZXR1cm4gaCYmdy5lcnJvcigiU2tpcHBlZCBzZW5kaW5nIGV2ZW50IGJlY2F1c2UgYnVmZmVyIGlzIGZ1bGwuIiksaSgpLEgoe30pO3Rocm93IHR9KSl9LGZsdXNoOnQ9PmUuZHJhaW4odCl9fWNvbnN0IG5uPS9eKFxTKzpcXHxcLz8pKFtcc1xTXSo/KSgoPzpcLnsxLDJ9fFteL1xcXSs/fCkoXC5bXi4vXFxdKnwpKSg/OlsvXFxdKikkLztmdW5jdGlvbiBlbih0KXtjb25zdCBuPWZ1bmN0aW9uKHQpe2NvbnN0IG49dC5sZW5ndGg+MTAyND9gPHRydW5jYXRlZD4ke3Quc2xpY2UoLTEwMjQpfWA6dCxlPW5uLmV4ZWMobik7cmV0dXJuIGU/ZS5zbGljZSgxKTpbXX0odCksZT1uWzBdfHwiIjtsZXQgcj1uWzFdO3JldHVybiBlfHxyPyhyJiYocj1yLnNsaWNlKDAsci5sZW5ndGgtMSkpLGUrcik6Ii4ifWZ1bmN0aW9uIHJuKHQsbj0hMSl7cmV0dXJuIShufHx0JiYhdC5zdGFydHNXaXRoKCIvIikmJiF0Lm1hdGNoKC9eW0EtWl06LykmJiF0LnN0YXJ0c1dpdGgoIi4iKSYmIXQubWF0Y2goL15bYS16QS1aXShbYS16QS1aMC05LlwtK10pKjpcL1wvLykpJiZ2b2lkIDAhPT10JiYhdC5pbmNsdWRlcygibm9kZV9tb2R1bGVzLyIpfWNvbnN0IG9uPVN5bWJvbCgiQWdlbnRCYXNlSW50ZXJuYWxTdGF0ZSIpO2NsYXNzIHNuIGV4dGVuZHMgcy5BZ2VudHtjb25zdHJ1Y3Rvcih0KXtzdXBlcih0KSx0aGlzW29uXT17fX1pc1NlY3VyZUVuZHBvaW50KHQpe2lmKHQpe2lmKCJib29sZWFuIj09dHlwZW9mIHQuc2VjdXJlRW5kcG9pbnQpcmV0dXJuIHQuc2VjdXJlRW5kcG9pbnQ7aWYoInN0cmluZyI9PXR5cGVvZiB0LnByb3RvY29sKXJldHVybiJodHRwczoiPT09dC5wcm90b2NvbH1jb25zdHtzdGFjazpufT1uZXcgRXJyb3I7cmV0dXJuInN0cmluZyI9PXR5cGVvZiBuJiZuLnNwbGl0KCJcbiIpLnNvbWUoKHQ9Pi0xIT09dC5pbmRleE9mKCIoaHR0cHMuanM6Iil8fC0xIT09dC5pbmRleE9mKCJub2RlOmh0dHBzOiIpKSl9Y3JlYXRlU29ja2V0KHQsbixlKXtjb25zdCByPXsuLi5uLHNlY3VyZUVuZHBvaW50OnRoaXMuaXNTZWN1cmVFbmRwb2ludChuKX07UHJvbWlzZS5yZXNvbHZlKCkudGhlbigoKCk9PnRoaXMuY29ubmVjdCh0LHIpKSkudGhlbigobz0+e2lmKG8gaW5zdGFuY2VvZiBzLkFnZW50KXJldHVybiBvLmFkZFJlcXVlc3QodCxyKTt0aGlzW29uXS5jdXJyZW50U29ja2V0PW8sc3VwZXIuY3JlYXRlU29ja2V0KHQsbixlKX0pLGUpfWNyZWF0ZUNvbm5lY3Rpb24oKXtjb25zdCB0PXRoaXNbb25dLmN1cnJlbnRTb2NrZXQ7aWYodGhpc1tvbl0uY3VycmVudFNvY2tldD12b2lkIDAsIXQpdGhyb3cgbmV3IEVycm9yKCJObyBzb2NrZXQgd2FzIHJldHVybmVkIGluIHRoZSBgY29ubmVjdCgpYCBmdW5jdGlvbiIpO3JldHVybiB0fWdldCBkZWZhdWx0UG9ydCgpe3JldHVybiB0aGlzW29uXS5kZWZhdWx0UG9ydD8/KCJodHRwczoiPT09dGhpcy5wcm90b2NvbD80NDM6ODApfXNldCBkZWZhdWx0UG9ydCh0KXt0aGlzW29uXSYmKHRoaXNbb25dLmRlZmF1bHRQb3J0PXQpfWdldCBwcm90b2NvbCgpe3JldHVybiB0aGlzW29uXS5wcm90b2NvbD8/KHRoaXMuaXNTZWN1cmVFbmRwb2ludCgpPyJodHRwczoiOiJodHRwOiIpfXNldCBwcm90b2NvbCh0KXt0aGlzW29uXSYmKHRoaXNbb25dLnByb3RvY29sPXQpfX1mdW5jdGlvbiBjbiguLi50KXt3LmxvZygiW2h0dHBzLXByb3h5LWFnZW50OnBhcnNlLXByb3h5LXJlc3BvbnNlXSIsLi4udCl9ZnVuY3Rpb24gdW4odCl7cmV0dXJuIG5ldyBQcm9taXNlKCgobixlKT0+e2xldCByPTA7Y29uc3Qgbz1bXTtmdW5jdGlvbiBzKCl7Y29uc3QgYz10LnJlYWQoKTtjP2Z1bmN0aW9uKGMpe28ucHVzaChjKSxyKz1jLmxlbmd0aDtjb25zdCB1PUJ1ZmZlci5jb25jYXQobyxyKSxhPXUuaW5kZXhPZigiXHJcblxyXG4iKTtpZigtMT09PWEpcmV0dXJuIGNuKCJoYXZlIG5vdCByZWNlaXZlZCBlbmQgb2YgSFRUUCBoZWFkZXJzIHlldC4uLiIpLHZvaWQgcygpO2NvbnN0IGY9dS5zdWJhcnJheSgwLGEpLnRvU3RyaW5nKCJhc2NpaSIpLnNwbGl0KCJcclxuIiksaD1mLnNoaWZ0KCk7aWYoIWgpcmV0dXJuIHQuZGVzdHJveSgpLGUobmV3IEVycm9yKCJObyBoZWFkZXIgcmVjZWl2ZWQgZnJvbSBwcm94eSBDT05ORUNUIHJlc3BvbnNlIikpO2NvbnN0IHA9aC5zcGxpdCgiICIpLGw9KyhwWzFdfHwwKSxkPXAuc2xpY2UoMikuam9pbigiICIpLG09e307Zm9yKGNvbnN0IG4gb2YgZil7aWYoIW4pY29udGludWU7Y29uc3Qgcj1uLmluZGV4T2YoIjoiKTtpZigtMT09PXIpcmV0dXJuIHQuZGVzdHJveSgpLGUobmV3IEVycm9yKGBJbnZhbGlkIGhlYWRlciBmcm9tIHByb3h5IENPTk5FQ1QgcmVzcG9uc2U6ICIke259ImApKTtjb25zdCBvPW4uc2xpY2UoMCxyKS50b0xvd2VyQ2FzZSgpLHM9bi5zbGljZShyKzEpLnRyaW1TdGFydCgpLGk9bVtvXTsic3RyaW5nIj09dHlwZW9mIGk/bVtvXT1baSxzXTpBcnJheS5pc0FycmF5KGkpP2kucHVzaChzKTptW29dPXN9Y24oImdvdCBwcm94eSBzZXJ2ZXIgcmVzcG9uc2U6ICVvICVvIixoLG0pLGkoKSxuKHtjb25uZWN0OntzdGF0dXNDb2RlOmwsc3RhdHVzVGV4dDpkLGhlYWRlcnM6bX0sYnVmZmVyZWQ6dX0pfShjKTp0Lm9uY2UoInJlYWRhYmxlIixzKX1mdW5jdGlvbiBpKCl7dC5yZW1vdmVMaXN0ZW5lcigiZW5kIixjKSx0LnJlbW92ZUxpc3RlbmVyKCJlcnJvciIsdSksdC5yZW1vdmVMaXN0ZW5lcigicmVhZGFibGUiLHMpfWZ1bmN0aW9uIGMoKXtpKCksY24oIm9uZW5kIiksZShuZXcgRXJyb3IoIlByb3h5IGNvbm5lY3Rpb24gZW5kZWQgYmVmb3JlIHJlY2VpdmluZyBDT05ORUNUIHJlc3BvbnNlIikpfWZ1bmN0aW9uIHUodCl7aSgpLGNuKCJvbmVycm9yICVvIix0KSxlKHQpfXQub24oImVycm9yIix1KSx0Lm9uKCJlbmQiLGMpLHMoKX0pKX1mdW5jdGlvbiBhbiguLi50KXt3LmxvZygiW2h0dHBzLXByb3h5LWFnZW50XSIsLi4udCl9Y2xhc3MgZm4gZXh0ZW5kcyBzbntzdGF0aWMgX19pbml0U3RhdGljKCl7dGhpcy5wcm90b2NvbHM9WyJodHRwIiwiaHR0cHMiXX1jb25zdHJ1Y3Rvcih0LG4pe3N1cGVyKG4pLHRoaXMub3B0aW9ucz17fSx0aGlzLnByb3h5PSJzdHJpbmciPT10eXBlb2YgdD9uZXcgVVJMKHQpOnQsdGhpcy5wcm94eUhlYWRlcnM9bj8uaGVhZGVycz8/e30sYW4oIkNyZWF0aW5nIG5ldyBIdHRwc1Byb3h5QWdlbnQgaW5zdGFuY2U6ICVvIix0aGlzLnByb3h5LmhyZWYpO2NvbnN0IGU9KHRoaXMucHJveHkuaG9zdG5hbWV8fHRoaXMucHJveHkuaG9zdCkucmVwbGFjZSgvXlxbfFxdJC9nLCIiKSxyPXRoaXMucHJveHkucG9ydD9wYXJzZUludCh0aGlzLnByb3h5LnBvcnQsMTApOiJodHRwczoiPT09dGhpcy5wcm94eS5wcm90b2NvbD80NDM6ODA7dGhpcy5jb25uZWN0T3B0cz17QUxQTlByb3RvY29sczpbImh0dHAvMS4xIl0sLi4ubj9wbihuLCJoZWFkZXJzIik6bnVsbCxob3N0OmUscG9ydDpyfX1hc3luYyBjb25uZWN0KHQsbil7Y29uc3R7cHJveHk6ZX09dGhpcztpZighbi5ob3N0KXRocm93IG5ldyBUeXBlRXJyb3IoJ05vICJob3N0IiBwcm92aWRlZCcpO2xldCByO2lmKCJodHRwczoiPT09ZS5wcm90b2NvbCl7YW4oIkNyZWF0aW5nIGB0bHMuU29ja2V0YDogJW8iLHRoaXMuY29ubmVjdE9wdHMpO2NvbnN0IHQ9dGhpcy5jb25uZWN0T3B0cy5zZXJ2ZXJuYW1lfHx0aGlzLmNvbm5lY3RPcHRzLmhvc3Q7cj1mLmNvbm5lY3Qoey4uLnRoaXMuY29ubmVjdE9wdHMsc2VydmVybmFtZTp0JiZhLmlzSVAodCk/dm9pZCAwOnR9KX1lbHNlIGFuKCJDcmVhdGluZyBgbmV0LlNvY2tldGA6ICVvIix0aGlzLmNvbm5lY3RPcHRzKSxyPWEuY29ubmVjdCh0aGlzLmNvbm5lY3RPcHRzKTtjb25zdCBvPSJmdW5jdGlvbiI9PXR5cGVvZiB0aGlzLnByb3h5SGVhZGVycz90aGlzLnByb3h5SGVhZGVycygpOnsuLi50aGlzLnByb3h5SGVhZGVyc30scz1hLmlzSVB2NihuLmhvc3QpP2BbJHtuLmhvc3R9XWA6bi5ob3N0O2xldCBpPWBDT05ORUNUICR7c306JHtuLnBvcnR9IEhUVFAvMS4xXHJcbmA7aWYoZS51c2VybmFtZXx8ZS5wYXNzd29yZCl7Y29uc3QgdD1gJHtkZWNvZGVVUklDb21wb25lbnQoZS51c2VybmFtZSl9OiR7ZGVjb2RlVVJJQ29tcG9uZW50KGUucGFzc3dvcmQpfWA7b1siUHJveHktQXV0aG9yaXphdGlvbiJdPWBCYXNpYyAke0J1ZmZlci5mcm9tKHQpLnRvU3RyaW5nKCJiYXNlNjQiKX1gfW8uSG9zdD1gJHtzfToke24ucG9ydH1gLG9bIlByb3h5LUNvbm5lY3Rpb24iXXx8KG9bIlByb3h5LUNvbm5lY3Rpb24iXT10aGlzLmtlZXBBbGl2ZT8iS2VlcC1BbGl2ZSI6ImNsb3NlIik7Zm9yKGNvbnN0IHQgb2YgT2JqZWN0LmtleXMobykpaSs9YCR7dH06ICR7b1t0XX1cclxuYDtjb25zdCBjPXVuKHIpO3Iud3JpdGUoYCR7aX1cclxuYCk7Y29uc3R7Y29ubmVjdDp1LGJ1ZmZlcmVkOmh9PWF3YWl0IGM7aWYodC5lbWl0KCJwcm94eUNvbm5lY3QiLHUpLHRoaXMuZW1pdCgicHJveHlDb25uZWN0Iix1LHQpLDIwMD09PXUuc3RhdHVzQ29kZSl7aWYodC5vbmNlKCJzb2NrZXQiLGhuKSxuLnNlY3VyZUVuZHBvaW50KXthbigiVXBncmFkaW5nIHNvY2tldCBjb25uZWN0aW9uIHRvIFRMUyIpO2NvbnN0IHQ9bi5zZXJ2ZXJuYW1lfHxuLmhvc3Q7cmV0dXJuIGYuY29ubmVjdCh7Li4ucG4obiwiaG9zdCIsInBhdGgiLCJwb3J0Iiksc29ja2V0OnIsc2VydmVybmFtZTphLmlzSVAodCk/dm9pZCAwOnR9KX1yZXR1cm4gcn1yLmRlc3Ryb3koKTtjb25zdCBwPW5ldyBhLlNvY2tldCh7d3JpdGFibGU6ITF9KTtyZXR1cm4gcC5yZWFkYWJsZT0hMCx0Lm9uY2UoInNvY2tldCIsKHQ9PnthbigiUmVwbGF5aW5nIHByb3h5IGJ1ZmZlciBmb3IgZmFpbGVkIHJlcXVlc3QiKSx0LnB1c2goaCksdC5wdXNoKG51bGwpfSkpLHB9fWZ1bmN0aW9uIGhuKHQpe3QucmVzdW1lKCl9ZnVuY3Rpb24gcG4odCwuLi5uKXtjb25zdCBlPXt9O2xldCByO2ZvcihyIGluIHQpbi5pbmNsdWRlcyhyKXx8KGVbcl09dFtyXSk7cmV0dXJuIGV9Zm4uX19pbml0U3RhdGljKCk7Y29uc3QgbG49MzI3Njg7ZnVuY3Rpb24gZG4odCl7cmV0dXJuIHQucmVwbGFjZSgvXltBLVpdOi8sIiIpLnJlcGxhY2UoL1xcL2csIi8iKX1jb25zdCBtbj1uO2xldCBnbix5bj0wLGJuPXt9O2Z1bmN0aW9uIF9uKHQpe21uLmRlYnVnJiZjb25zb2xlLmxvZyhgW0FOUiBXb3JrZXJdICR7dH1gKX12YXIgdm4sd24sU247Y29uc3QgJG49ZnVuY3Rpb24odCl7bGV0IG47dHJ5e249bmV3IFVSTCh0LnVybCl9Y2F0Y2gobil7cmV0dXJuIHYoKCgpPT57Y29uc29sZS53YXJuKCJbQHNlbnRyeS9ub2RlXTogSW52YWxpZCBkc24gb3IgdHVubmVsIG9wdGlvbiwgd2lsbCBub3Qgc2VuZCBhbnkgZXZlbnRzLiBUaGUgdHVubmVsIG9wdGlvbiBtdXN0IGJlIGEgZnVsbCBVUkwgd2hlbiB1c2VkLiIpfSkpLHRuKHQsKCgpPT5Qcm9taXNlLnJlc29sdmUoe30pKSl9Y29uc3QgZT0iaHR0cHM6Ij09PW4ucHJvdG9jb2wscj1mdW5jdGlvbih0LG4pe2NvbnN0e25vX3Byb3h5OmV9PXByb2Nlc3MuZW52LHI9ZT8uc3BsaXQoIiwiKS5zb21lKChuPT50Lmhvc3QuZW5kc1dpdGgobil8fHQuaG9zdG5hbWUuZW5kc1dpdGgobikpKTtyZXR1cm4gcj92b2lkIDA6bn0obix0LnByb3h5fHwoZT9wcm9jZXNzLmVudi5odHRwc19wcm94eTp2b2lkIDApfHxwcm9jZXNzLmVudi5odHRwX3Byb3h5KSxvPWU/aTpzLGE9dm9pZCAwIT09dC5rZWVwQWxpdmUmJnQua2VlcEFsaXZlLGY9cj9uZXcgZm4ocik6bmV3IG8uQWdlbnQoe2tlZXBBbGl2ZTphLG1heFNvY2tldHM6MzAsdGltZW91dDoyZTN9KSxoPWZ1bmN0aW9uKHQsbixlKXtjb25zdHtob3N0bmFtZTpyLHBhdGhuYW1lOm8scG9ydDpzLHByb3RvY29sOmksc2VhcmNoOmF9PW5ldyBVUkwodC51cmwpO3JldHVybiBmdW5jdGlvbihmKXtyZXR1cm4gbmV3IFByb21pc2UoKChoLHApPT57RnQoKCgpPT57bGV0IGw9ZnVuY3Rpb24odCl7cmV0dXJuIG5ldyBjKHtyZWFkKCl7dGhpcy5wdXNoKHQpLHRoaXMucHVzaChudWxsKX19KX0oZi5ib2R5KTtjb25zdCBkPXsuLi50LmhlYWRlcnN9O2YuYm9keS5sZW5ndGg+bG4mJihkWyJjb250ZW50LWVuY29kaW5nIl09Imd6aXAiLGw9bC5waXBlKHUoKSkpO2NvbnN0IG09bi5yZXF1ZXN0KHttZXRob2Q6IlBPU1QiLGFnZW50OmUsaGVhZGVyczpkLGhvc3RuYW1lOnIscGF0aDpgJHtvfSR7YX1gLHBvcnQ6cyxwcm90b2NvbDppLGNhOnQuY2FDZXJ0c30sKHQ9Pnt0Lm9uKCJkYXRhIiwoKCk9Pnt9KSksdC5vbigiZW5kIiwoKCk9Pnt9KSksdC5zZXRFbmNvZGluZygidXRmOCIpO2NvbnN0IG49dC5oZWFkZXJzWyJyZXRyeS1hZnRlciJdPz9udWxsLGU9dC5oZWFkZXJzWyJ4LXNlbnRyeS1yYXRlLWxpbWl0cyJdPz9udWxsO2goe3N0YXR1c0NvZGU6dC5zdGF0dXNDb2RlLGhlYWRlcnM6eyJyZXRyeS1hZnRlciI6biwieC1zZW50cnktcmF0ZS1saW1pdHMiOkFycmF5LmlzQXJyYXkoZSk/ZVswXXx8bnVsbDplfX0pfSkpO20ub24oImVycm9yIixwKSxsLnBpcGUobSl9KSl9KSl9fSh0LHQuaHR0cE1vZHVsZT8/byxmKTtyZXR1cm4gdG4odCxoKX0oe3VybDoodm49bW4uZHNuLHduPW1uLnR1bm5lbCxTbj1tbi5zZGtNZXRhZGF0YS5zZGssd258fGAke2Z1bmN0aW9uKHQpe3JldHVybmAke2Z1bmN0aW9uKHQpe2NvbnN0IG49dC5wcm90b2NvbD9gJHt0LnByb3RvY29sfTpgOiIiLGU9dC5wb3J0P2A6JHt0LnBvcnR9YDoiIjtyZXR1cm5gJHtufS8vJHt0Lmhvc3R9JHtlfSR7dC5wYXRoP2AvJHt0LnBhdGh9YDoiIn0vYXBpL2B9KHQpfSR7dC5wcm9qZWN0SWR9L2VudmVsb3BlL2B9KHZuKX0/JHtmdW5jdGlvbih0LG4pe2NvbnN0IGU9e3NlbnRyeV92ZXJzaW9uOkt0fTtyZXR1cm4gdC5wdWJsaWNLZXkmJihlLnNlbnRyeV9rZXk9dC5wdWJsaWNLZXkpLG4mJihlLnNlbnRyeV9jbGllbnQ9YCR7bi5uYW1lfS8ke24udmVyc2lvbn1gKSxuZXcgVVJMU2VhcmNoUGFyYW1zKGUpLnRvU3RyaW5nKCl9KHZuLFNuKX1gKX0pO2FzeW5jIGZ1bmN0aW9uIEVuKCl7aWYoZ24pe19uKCJTZW5kaW5nIGFibm9ybWFsIHNlc3Npb24iKSxLKGduLHtzdGF0dXM6ImFibm9ybWFsIixhYm5vcm1hbF9tZWNoYW5pc206ImFucl9mb3JlZ3JvdW5kIixyZWxlYXNlOm1uLnJlbGVhc2UsZW52aXJvbm1lbnQ6bW4uZW52aXJvbm1lbnR9KTtjb25zdCB0PWZ1bmN0aW9uKHQsbixlLHIpe2NvbnN0IG89WXQoZSk7cmV0dXJuIE10KHtzZW50X2F0OihuZXcgRGF0ZSkudG9JU09TdHJpbmcoKSwuLi5vJiZ7c2RrOm99LC4uLiEhciYmbiYme2RzbjpPdChuKX19LFsiYWdncmVnYXRlcyJpbiB0P1t7dHlwZToic2Vzc2lvbnMifSx0XTpbe3R5cGU6InNlc3Npb24ifSx0LnRvSlNPTigpXV0pfShnbixtbi5kc24sbW4uc2RrTWV0YWRhdGEsbW4udHVubmVsKTtfbihKU09OLnN0cmluZ2lmeSh0KSksYXdhaXQgJG4uc2VuZCh0KTt0cnl7ZT8ucG9zdE1lc3NhZ2UoInNlc3Npb24tZW5kZWQiKX1jYXRjaCh0KXt9fX1mdW5jdGlvbiB4bih0KXtpZighdClyZXR1cm47Y29uc3Qgbj1mdW5jdGlvbih0KXtpZighdC5sZW5ndGgpcmV0dXJuW107Y29uc3Qgbj1BcnJheS5mcm9tKHQpO3JldHVybi9zZW50cnlXcmFwcGVkLy50ZXN0KHgobikuZnVuY3Rpb258fCIiKSYmbi5wb3AoKSxuLnJldmVyc2UoKSxFLnRlc3QoeChuKS5mdW5jdGlvbnx8IiIpJiYobi5wb3AoKSxFLnRlc3QoeChuKS5mdW5jdGlvbnx8IiIpJiZuLnBvcCgpKSxuLnNsaWNlKDAsUykubWFwKCh0PT4oey4uLnQsZmlsZW5hbWU6dC5maWxlbmFtZXx8eChuKS5maWxlbmFtZSxmdW5jdGlvbjp0LmZ1bmN0aW9ufHwkfSkpKX0odCk7aWYobW4uYXBwUm9vdFBhdGgpZm9yKGNvbnN0IHQgb2Ygbil0LmZpbGVuYW1lJiYodC5maWxlbmFtZT1VdCh0LmZpbGVuYW1lLG1uLmFwcFJvb3RQYXRoKSk7cmV0dXJuIG59YXN5bmMgZnVuY3Rpb24gTm4odCxuKXtpZih5bj49bW4ubWF4QW5yRXZlbnRzKXJldHVybjt5bis9MSxhd2FpdCBFbigpLF9uKCJTZW5kaW5nIGV2ZW50Iik7Y29uc3QgZT17ZXZlbnRfaWQ6WSgpLGNvbnRleHRzOm1uLmNvbnRleHRzLHJlbGVhc2U6bW4ucmVsZWFzZSxlbnZpcm9ubWVudDptbi5lbnZpcm9ubWVudCxkaXN0Om1uLmRpc3QscGxhdGZvcm06Im5vZGUiLGxldmVsOiJlcnJvciIsZXhjZXB0aW9uOnt2YWx1ZXM6W3t0eXBlOiJBcHBsaWNhdGlvbk5vdFJlc3BvbmRpbmciLHZhbHVlOmBBcHBsaWNhdGlvbiBOb3QgUmVzcG9uZGluZyBmb3IgYXQgbGVhc3QgJHttbi5hbnJUaHJlc2hvbGR9IG1zYCxzdGFja3RyYWNlOntmcmFtZXM6eG4odCl9LG1lY2hhbmlzbTp7dHlwZToiQU5SIn19XX0sdGFnczptbi5zdGF0aWNUYWdzfTtuJiZmdW5jdGlvbih0LG4pe2lmKFd0KHQsbiksIXQuY29udGV4dHM/LnRyYWNlKXtjb25zdHt0cmFjZUlkOmUscGFyZW50U3BhbklkOnIscHJvcGFnYXRpb25TcGFuSWQ6b309bi5wcm9wYWdhdGlvbkNvbnRleHQ7dC5jb250ZXh0cz17dHJhY2U6e3RyYWNlX2lkOmUsc3Bhbl9pZDpvfHxaKCkscGFyZW50X3NwYW5faWQ6cn0sLi4udC5jb250ZXh0c319fShlLG4pLGZ1bmN0aW9uKHQpe2lmKDA9PT1PYmplY3Qua2V5cyhibikubGVuZ3RoKXJldHVybjtjb25zdCBuPW1uLmFwcFJvb3RQYXRoP3t9OmJuO2lmKG1uLmFwcFJvb3RQYXRoKWZvcihjb25zdFt0LGVdb2YgT2JqZWN0LmVudHJpZXMoYm4pKW5bVXQodCxtbi5hcHBSb290UGF0aCldPWU7Y29uc3QgZT1uZXcgTWFwO2Zvcihjb25zdCByIG9mIHQuZXhjZXB0aW9uPy52YWx1ZXN8fFtdKWZvcihjb25zdCB0IG9mIHIuc3RhY2t0cmFjZT8uZnJhbWVzfHxbXSl7Y29uc3Qgcj10LmFic19wYXRofHx0LmZpbGVuYW1lO3ImJm5bcl0mJmUuc2V0KHIsbltyXSl9aWYoZS5zaXplPjApe2NvbnN0IG49W107Zm9yKGNvbnN0W3Qscl1vZiBlLmVudHJpZXMoKSluLnB1c2goe3R5cGU6InNvdXJjZW1hcCIsY29kZV9maWxlOnQsZGVidWdfaWQ6cn0pO3QuZGVidWdfbWV0YT17aW1hZ2VzOm59fX0oZSk7Y29uc3Qgcj16dChlLG1uLmRzbixtbi5zZGtNZXRhZGF0YSxtbi50dW5uZWwpO19uKEpTT04uc3RyaW5naWZ5KHIpKSxhd2FpdCAkbi5zZW5kKHIpLGF3YWl0ICRuLmZsdXNoKDJlMykseW4+PW1uLm1heEFuckV2ZW50cyYmc2V0VGltZW91dCgoKCk9Pntwcm9jZXNzLmV4aXQoMCl9KSw1ZTMpfWxldCBUbjtpZihfbigiU3RhcnRlZCIpLG1uLmNhcHR1cmVTdGFja1RyYWNlKXtfbigiQ29ubmVjdGluZyB0byBkZWJ1Z2dlciIpO2NvbnN0IG49bmV3IHQ7bi5jb25uZWN0VG9NYWluVGhyZWFkKCksX24oIkNvbm5lY3RlZCB0byBkZWJ1Z2dlciIpO2NvbnN0IGU9bmV3IE1hcDtuLm9uKCJEZWJ1Z2dlci5zY3JpcHRQYXJzZWQiLCh0PT57ZS5zZXQodC5wYXJhbXMuc2NyaXB0SWQsdC5wYXJhbXMudXJsKX0pKSxuLm9uKCJEZWJ1Z2dlci5wYXVzZWQiLCh0PT57aWYoIm90aGVyIj09PXQucGFyYW1zLnJlYXNvbil0cnl7X24oIkRlYnVnZ2VyIHBhdXNlZCIpO2NvbnN0IHM9Wy4uLnQucGFyYW1zLmNhbGxGcmFtZXNdLGk9bW4uYXBwUm9vdFBhdGg/ZnVuY3Rpb24odD0ocHJvY2Vzcy5hcmd2WzFdP2VuKHByb2Nlc3MuYXJndlsxXSk6cHJvY2Vzcy5jd2QoKSksbj0iXFwiPT09byl7Y29uc3QgZT1uP2RuKHQpOnQ7cmV0dXJuIHQ9PntpZighdClyZXR1cm47Y29uc3Qgbz1uP2RuKHQpOnQ7bGV0e2RpcjpzLGJhc2U6aSxleHQ6Y309ci5wYXJzZShvKTsiLmpzIiE9PWMmJiIubWpzIiE9PWMmJiIuY2pzIiE9PWN8fChpPWkuc2xpY2UoMCwtMSpjLmxlbmd0aCkpO2NvbnN0IHU9ZGVjb2RlVVJJQ29tcG9uZW50KGkpO3N8fChzPSIuIik7Y29uc3QgYT1zLmxhc3RJbmRleE9mKCIvbm9kZV9tb2R1bGVzIik7aWYoYT4tMSlyZXR1cm5gJHtzLnNsaWNlKGErMTQpLnJlcGxhY2UoL1wvL2csIi4iKX06JHt1fWA7aWYocy5zdGFydHNXaXRoKGUpKXtjb25zdCB0PXMuc2xpY2UoZS5sZW5ndGgrMSkucmVwbGFjZSgvXC8vZywiLiIpO3JldHVybiB0P2Ake3R9OiR7dX1gOnV9cmV0dXJuIHV9fShtbi5hcHBSb290UGF0aCk6KCk9Pnt9LGM9cy5tYXAoKHQ9PmZ1bmN0aW9uKHQsbixlKXtjb25zdCByPW4/bi5yZXBsYWNlKC9eZmlsZTpcL1wvLywiIik6dm9pZCAwLG89dC5sb2NhdGlvbi5jb2x1bW5OdW1iZXI/dC5sb2NhdGlvbi5jb2x1bW5OdW1iZXIrMTp2b2lkIDAscz10LmxvY2F0aW9uLmxpbmVOdW1iZXI/dC5sb2NhdGlvbi5saW5lTnVtYmVyKzE6dm9pZCAwO3JldHVybntmaWxlbmFtZTpyLG1vZHVsZTplKHIpLGZ1bmN0aW9uOnQuZnVuY3Rpb25OYW1lfHwkLGNvbG5vOm8sbGluZW5vOnMsaW5fYXBwOnI/cm4ocik6dm9pZCAwfX0odCxlLmdldCh0LmxvY2F0aW9uLnNjcmlwdElkKSxpKSkpLHU9c2V0VGltZW91dCgoKCk9PntObihjKS50aGVuKG51bGwsKCgpPT57X24oIlNlbmRpbmcgQU5SIGV2ZW50IGZhaWxlZC4iKX0pKX0pLDVlMyk7bi5wb3N0KCJSdW50aW1lLmV2YWx1YXRlIix7ZXhwcmVzc2lvbjoiZ2xvYmFsLl9fU0VOVFJZX0dFVF9TQ09QRVNfXygpOyIsc2lsZW50OiEwLHJldHVybkJ5VmFsdWU6ITB9LCgodCxlKT0+e3QmJl9uKGBFcnJvciBleGVjdXRpbmcgc2NyaXB0OiAnJHt0Lm1lc3NhZ2V9J2ApLGNsZWFyVGltZW91dCh1KTtjb25zdCByPWU/LnJlc3VsdD9lLnJlc3VsdC52YWx1ZTp2b2lkIDA7bi5wb3N0KCJEZWJ1Z2dlci5yZXN1bWUiKSxuLnBvc3QoIkRlYnVnZ2VyLmRpc2FibGUiKSxObihjLHIpLnRoZW4obnVsbCwoKCk9PntfbigiU2VuZGluZyBBTlIgZXZlbnQgZmFpbGVkLiIpfSkpfSkpfWNhdGNoKHQpe3Rocm93IG4ucG9zdCgiRGVidWdnZXIucmVzdW1lIiksbi5wb3N0KCJEZWJ1Z2dlci5kaXNhYmxlIiksdH19KSksVG49KCk9Pnt0cnl7bi5wb3N0KCJEZWJ1Z2dlci5lbmFibGUiLCgoKT0+e24ucG9zdCgiRGVidWdnZXIucGF1c2UiKX0pKX1jYXRjaCh0KXt9fX1jb25zdHtwb2xsOkNufT1mdW5jdGlvbih0LG4sZSxyKXtjb25zdCBvPXQoKTtsZXQgcz0hMSxpPSEwO3JldHVybiBzZXRJbnRlcnZhbCgoKCk9Pntjb25zdCB0PW8uZ2V0VGltZU1zKCk7ITE9PT1zJiZ0Pm4rZSYmKHM9ITAsaSYmcigpKSx0PG4rZSYmKHM9ITEpfSksMjApLHtwb2xsOigpPT57by5yZXNldCgpfSxlbmFibGVkOnQ9PntpPXR9fX0oKGZ1bmN0aW9uKCl7bGV0IHQ9cHJvY2Vzcy5ocnRpbWUoKTtyZXR1cm57Z2V0VGltZU1zOigpPT57Y29uc3RbbixlXT1wcm9jZXNzLmhydGltZSh0KTtyZXR1cm4gTWF0aC5mbG9vcigxZTMqbitlLzFlNil9LHJlc2V0OigpPT57dD1wcm9jZXNzLmhydGltZSgpfX19KSxtbi5wb2xsSW50ZXJ2YWwsbW4uYW5yVGhyZXNob2xkLChmdW5jdGlvbigpe19uKCJXYXRjaGRvZyB0aW1lb3V0IiksVG4/KF9uKCJQYXVzaW5nIGRlYnVnZ2VyIHRvIGNhcHR1cmUgc3RhY2sgdHJhY2UiKSxUbigpKTooX24oIkNhcHR1cmluZyBldmVudCB3aXRob3V0IGEgc3RhY2sgdHJhY2UiKSxObigpLnRoZW4obnVsbCwoKCk9PntfbigiU2VuZGluZyBBTlIgZXZlbnQgZmFpbGVkIG9uIHdhdGNoZG9nIHRpbWVvdXQuIil9KSkpfSkpO2U/Lm9uKCJtZXNzYWdlIiwodD0+e3Quc2Vzc2lvbiYmKGduPVcodC5zZXNzaW9uKSksdC5kZWJ1Z0ltYWdlcyYmKGJuPXQuZGVidWdJbWFnZXMpLENuKCl9KSk7';
|
|
10
|
+
const base64WorkerScript = 'LyohIEBzZW50cnkvbm9kZSA5LjE1LjAgKGI0ZWE2NTMpIHwgaHR0cHM6Ly9naXRodWIuY29tL2dldHNlbnRyeS9zZW50cnktamF2YXNjcmlwdCAqLwppbXBvcnR7U2Vzc2lvbiBhcyB0fWZyb20ibm9kZTppbnNwZWN0b3IiO2ltcG9ydHt3b3JrZXJEYXRhIGFzIG4scGFyZW50UG9ydCBhcyBlfWZyb20ibm9kZTp3b3JrZXJfdGhyZWFkcyI7aW1wb3J0e3Bvc2l4IGFzIHIsc2VwIGFzIG99ZnJvbSJub2RlOnBhdGgiO2ltcG9ydCphcyBzIGZyb20ibm9kZTpodHRwIjtpbXBvcnQqYXMgaSBmcm9tIm5vZGU6aHR0cHMiO2ltcG9ydHtSZWFkYWJsZSBhcyBjfWZyb20ibm9kZTpzdHJlYW0iO2ltcG9ydHtjcmVhdGVHemlwIGFzIHV9ZnJvbSJub2RlOnpsaWIiO2ltcG9ydCphcyBhIGZyb20ibm9kZTpuZXQiO2ltcG9ydCphcyBmIGZyb20ibm9kZTp0bHMiO2NvbnN0IGg9InVuZGVmaW5lZCI9PXR5cGVvZiBfX1NFTlRSWV9ERUJVR19ffHxfX1NFTlRSWV9ERUJVR19fLHA9IjkuMTUuMCIsbD1nbG9iYWxUaGlzO2Z1bmN0aW9uIGQoKXtyZXR1cm4gbShsKSxsfWZ1bmN0aW9uIG0odCl7Y29uc3Qgbj10Ll9fU0VOVFJZX189dC5fX1NFTlRSWV9ffHx7fTtyZXR1cm4gbi52ZXJzaW9uPW4udmVyc2lvbnx8cCxuW3BdPW5bcF18fHt9fWZ1bmN0aW9uIGcodCxuLGU9bCl7Y29uc3Qgcj1lLl9fU0VOVFJZX189ZS5fX1NFTlRSWV9ffHx7fSxvPXJbcF09cltwXXx8e307cmV0dXJuIG9bdF18fChvW3RdPW4oKSl9Y29uc3QgeT1PYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO2Z1bmN0aW9uIGIodCxuKXtyZXR1cm4geS5jYWxsKHQpPT09YFtvYmplY3QgJHtufV1gfWZ1bmN0aW9uIF8odCl7cmV0dXJuIGIodCwiU3RyaW5nIil9ZnVuY3Rpb24gdih0KXtyZXR1cm4gYih0LCJPYmplY3QiKX1mdW5jdGlvbiB3KHQpe3JldHVybiBCb29sZWFuKHQ/LnRoZW4mJiJmdW5jdGlvbiI9PXR5cGVvZiB0LnRoZW4pfWZ1bmN0aW9uIFModCxuKXt0cnl7cmV0dXJuIHQgaW5zdGFuY2VvZiBufWNhdGNoKHQpe3JldHVybiExfX1jb25zdCAkPWwsRT04MDtmdW5jdGlvbiB4KHQsbil7Y29uc3QgZT10LHI9W107aWYoIWU/LnRhZ05hbWUpcmV0dXJuIiI7aWYoJC5IVE1MRWxlbWVudCYmZSBpbnN0YW5jZW9mIEhUTUxFbGVtZW50JiZlLmRhdGFzZXQpe2lmKGUuZGF0YXNldC5zZW50cnlDb21wb25lbnQpcmV0dXJuIGUuZGF0YXNldC5zZW50cnlDb21wb25lbnQ7aWYoZS5kYXRhc2V0LnNlbnRyeUVsZW1lbnQpcmV0dXJuIGUuZGF0YXNldC5zZW50cnlFbGVtZW50fXIucHVzaChlLnRhZ05hbWUudG9Mb3dlckNhc2UoKSk7Y29uc3Qgbz1uPy5sZW5ndGg/bi5maWx0ZXIoKHQ9PmUuZ2V0QXR0cmlidXRlKHQpKSkubWFwKCh0PT5bdCxlLmdldEF0dHJpYnV0ZSh0KV0pKTpudWxsO2lmKG8/Lmxlbmd0aClvLmZvckVhY2goKHQ9PntyLnB1c2goYFske3RbMF19PSIke3RbMV19Il1gKX0pKTtlbHNle2UuaWQmJnIucHVzaChgIyR7ZS5pZH1gKTtjb25zdCB0PWUuY2xhc3NOYW1lO2lmKHQmJl8odCkpe2NvbnN0IG49dC5zcGxpdCgvXHMrLyk7Zm9yKGNvbnN0IHQgb2YgbilyLnB1c2goYC4ke3R9YCl9fWNvbnN0IHM9WyJhcmlhLWxhYmVsIiwidHlwZSIsIm5hbWUiLCJ0aXRsZSIsImFsdCJdO2Zvcihjb25zdCB0IG9mIHMpe2NvbnN0IG49ZS5nZXRBdHRyaWJ1dGUodCk7biYmci5wdXNoKGBbJHt0fT0iJHtufSJdYCl9cmV0dXJuIHIuam9pbigiIil9Y29uc3QgTj0idW5kZWZpbmVkIj09dHlwZW9mIF9fU0VOVFJZX0RFQlVHX198fF9fU0VOVFJZX0RFQlVHX18sVD1bImRlYnVnIiwiaW5mbyIsIndhcm4iLCJlcnJvciIsImxvZyIsImFzc2VydCIsInRyYWNlIl0sQz17fTtmdW5jdGlvbiBSKHQpe2lmKCEoImNvbnNvbGUiaW4gbCkpcmV0dXJuIHQoKTtjb25zdCBuPWwuY29uc29sZSxlPXt9LHI9T2JqZWN0LmtleXMoQyk7ci5mb3JFYWNoKCh0PT57Y29uc3Qgcj1DW3RdO2VbdF09blt0XSxuW3RdPXJ9KSk7dHJ5e3JldHVybiB0KCl9ZmluYWxseXtyLmZvckVhY2goKHQ9PntuW3RdPWVbdF19KSl9fWNvbnN0IGs9ZygibG9nZ2VyIiwoZnVuY3Rpb24oKXtsZXQgdD0hMTtjb25zdCBuPXtlbmFibGU6KCk9Pnt0PSEwfSxkaXNhYmxlOigpPT57dD0hMX0saXNFbmFibGVkOigpPT50fTtyZXR1cm4gTj9ULmZvckVhY2goKGU9PntuW2VdPSguLi5uKT0+e3QmJlIoKCgpPT57bC5jb25zb2xlW2VdKGBTZW50cnkgTG9nZ2VyIFske2V9XTpgLC4uLm4pfSkpfX0pKTpULmZvckVhY2goKHQ9PntuW3RdPSgpPT57fX0pKSxufSkpO2Z1bmN0aW9uIGoodCxuPTApe3JldHVybiJzdHJpbmciIT10eXBlb2YgdHx8MD09PW58fHQubGVuZ3RoPD1uP3Q6YCR7dC5zbGljZSgwLG4pfS4uLmB9ZnVuY3Rpb24gRCh0KXtpZihmdW5jdGlvbih0KXtzd2l0Y2goeS5jYWxsKHQpKXtjYXNlIltvYmplY3QgRXJyb3JdIjpjYXNlIltvYmplY3QgRXhjZXB0aW9uXSI6Y2FzZSJbb2JqZWN0IERPTUV4Y2VwdGlvbl0iOmNhc2UiW29iamVjdCBXZWJBc3NlbWJseS5FeGNlcHRpb25dIjpyZXR1cm4hMDtkZWZhdWx0OnJldHVybiBTKHQsRXJyb3IpfX0odCkpcmV0dXJue21lc3NhZ2U6dC5tZXNzYWdlLG5hbWU6dC5uYW1lLHN0YWNrOnQuc3RhY2ssLi4uTyh0KX07aWYobj10LCJ1bmRlZmluZWQiIT10eXBlb2YgRXZlbnQmJlMobixFdmVudCkpe2NvbnN0IG49e3R5cGU6dC50eXBlLHRhcmdldDpJKHQudGFyZ2V0KSxjdXJyZW50VGFyZ2V0OkkodC5jdXJyZW50VGFyZ2V0KSwuLi5PKHQpfTtyZXR1cm4idW5kZWZpbmVkIiE9dHlwZW9mIEN1c3RvbUV2ZW50JiZTKHQsQ3VzdG9tRXZlbnQpJiYobi5kZXRhaWw9dC5kZXRhaWwpLG59cmV0dXJuIHQ7dmFyIG59ZnVuY3Rpb24gSSh0KXt0cnl7cmV0dXJuIG49dCwidW5kZWZpbmVkIiE9dHlwZW9mIEVsZW1lbnQmJlMobixFbGVtZW50KT9mdW5jdGlvbih0LG49e30pe2lmKCF0KXJldHVybiI8dW5rbm93bj4iO3RyeXtsZXQgZT10O2NvbnN0IHI9NSxvPVtdO2xldCBzPTAsaT0wO2NvbnN0IGM9IiA+ICIsdT1jLmxlbmd0aDtsZXQgYTtjb25zdCBmPUFycmF5LmlzQXJyYXkobik/bjpuLmtleUF0dHJzLGg9IUFycmF5LmlzQXJyYXkobikmJm4ubWF4U3RyaW5nTGVuZ3RofHxFO2Zvcig7ZSYmcysrPHImJihhPXgoZSxmKSwhKCJodG1sIj09PWF8fHM+MSYmaStvLmxlbmd0aCp1K2EubGVuZ3RoPj1oKSk7KW8ucHVzaChhKSxpKz1hLmxlbmd0aCxlPWUucGFyZW50Tm9kZTtyZXR1cm4gby5yZXZlcnNlKCkuam9pbihjKX1jYXRjaCh0KXtyZXR1cm4iPHVua25vd24+In19KHQpOk9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh0KX1jYXRjaCh0KXtyZXR1cm4iPHVua25vd24+In12YXIgbn1mdW5jdGlvbiBPKHQpe2lmKCJvYmplY3QiPT10eXBlb2YgdCYmbnVsbCE9PXQpe2NvbnN0IG49e307Zm9yKGNvbnN0IGUgaW4gdClPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodCxlKSYmKG5bZV09dFtlXSk7cmV0dXJuIG59cmV0dXJue319ZnVuY3Rpb24gQSh0PWZ1bmN0aW9uKCl7Y29uc3QgdD1sO3JldHVybiB0LmNyeXB0b3x8dC5tc0NyeXB0b30oKSl7bGV0IG49KCk9PjE2Kk1hdGgucmFuZG9tKCk7dHJ5e2lmKHQ/LnJhbmRvbVVVSUQpcmV0dXJuIHQucmFuZG9tVVVJRCgpLnJlcGxhY2UoLy0vZywiIik7dD8uZ2V0UmFuZG9tVmFsdWVzJiYobj0oKT0+e2NvbnN0IG49bmV3IFVpbnQ4QXJyYXkoMSk7cmV0dXJuIHQuZ2V0UmFuZG9tVmFsdWVzKG4pLG5bMF19KX1jYXRjaCh0KXt9cmV0dXJuKFsxZTddKzFlMys0ZTMrOGUzKzFlMTEpLnJlcGxhY2UoL1swMThdL2csKHQ9Pih0XigxNSZuKCkpPj50LzQpLnRvU3RyaW5nKDE2KSkpfWNvbnN0IFA9MWUzO2Z1bmN0aW9uIFUoKXtyZXR1cm4gRGF0ZS5ub3coKS9QfWNvbnN0IE09ZnVuY3Rpb24oKXtjb25zdHtwZXJmb3JtYW5jZTp0fT1sO2lmKCF0Py5ub3cpcmV0dXJuIFU7Y29uc3Qgbj1EYXRlLm5vdygpLXQubm93KCksZT1udWxsPT10LnRpbWVPcmlnaW4/bjp0LnRpbWVPcmlnaW47cmV0dXJuKCk9PihlK3Qubm93KCkpL1B9KCk7ZnVuY3Rpb24gTCh0KXtjb25zdCBuPU0oKSxlPXtzaWQ6QSgpLGluaXQ6ITAsdGltZXN0YW1wOm4sc3RhcnRlZDpuLGR1cmF0aW9uOjAsc3RhdHVzOiJvayIsZXJyb3JzOjAsaWdub3JlRHVyYXRpb246ITEsdG9KU09OOigpPT5mdW5jdGlvbih0KXtyZXR1cm57c2lkOmAke3Quc2lkfWAsaW5pdDp0LmluaXQsc3RhcnRlZDpuZXcgRGF0ZSgxZTMqdC5zdGFydGVkKS50b0lTT1N0cmluZygpLHRpbWVzdGFtcDpuZXcgRGF0ZSgxZTMqdC50aW1lc3RhbXApLnRvSVNPU3RyaW5nKCksc3RhdHVzOnQuc3RhdHVzLGVycm9yczp0LmVycm9ycyxkaWQ6Im51bWJlciI9PXR5cGVvZiB0LmRpZHx8InN0cmluZyI9PXR5cGVvZiB0LmRpZD9gJHt0LmRpZH1gOnZvaWQgMCxkdXJhdGlvbjp0LmR1cmF0aW9uLGFibm9ybWFsX21lY2hhbmlzbTp0LmFibm9ybWFsX21lY2hhbmlzbSxhdHRyczp7cmVsZWFzZTp0LnJlbGVhc2UsZW52aXJvbm1lbnQ6dC5lbnZpcm9ubWVudCxpcF9hZGRyZXNzOnQuaXBBZGRyZXNzLHVzZXJfYWdlbnQ6dC51c2VyQWdlbnR9fX0oZSl9O3JldHVybiB0JiZCKGUsdCksZX1mdW5jdGlvbiBCKHQsbj17fSl7aWYobi51c2VyJiYoIXQuaXBBZGRyZXNzJiZuLnVzZXIuaXBfYWRkcmVzcyYmKHQuaXBBZGRyZXNzPW4udXNlci5pcF9hZGRyZXNzKSx0LmRpZHx8bi5kaWR8fCh0LmRpZD1uLnVzZXIuaWR8fG4udXNlci5lbWFpbHx8bi51c2VyLnVzZXJuYW1lKSksdC50aW1lc3RhbXA9bi50aW1lc3RhbXB8fE0oKSxuLmFibm9ybWFsX21lY2hhbmlzbSYmKHQuYWJub3JtYWxfbWVjaGFuaXNtPW4uYWJub3JtYWxfbWVjaGFuaXNtKSxuLmlnbm9yZUR1cmF0aW9uJiYodC5pZ25vcmVEdXJhdGlvbj1uLmlnbm9yZUR1cmF0aW9uKSxuLnNpZCYmKHQuc2lkPTMyPT09bi5zaWQubGVuZ3RoP24uc2lkOkEoKSksdm9pZCAwIT09bi5pbml0JiYodC5pbml0PW4uaW5pdCksIXQuZGlkJiZuLmRpZCYmKHQuZGlkPWAke24uZGlkfWApLCJudW1iZXIiPT10eXBlb2Ygbi5zdGFydGVkJiYodC5zdGFydGVkPW4uc3RhcnRlZCksdC5pZ25vcmVEdXJhdGlvbil0LmR1cmF0aW9uPXZvaWQgMDtlbHNlIGlmKCJudW1iZXIiPT10eXBlb2Ygbi5kdXJhdGlvbil0LmR1cmF0aW9uPW4uZHVyYXRpb247ZWxzZXtjb25zdCBuPXQudGltZXN0YW1wLXQuc3RhcnRlZDt0LmR1cmF0aW9uPW4+PTA/bjowfW4ucmVsZWFzZSYmKHQucmVsZWFzZT1uLnJlbGVhc2UpLG4uZW52aXJvbm1lbnQmJih0LmVudmlyb25tZW50PW4uZW52aXJvbm1lbnQpLCF0LmlwQWRkcmVzcyYmbi5pcEFkZHJlc3MmJih0LmlwQWRkcmVzcz1uLmlwQWRkcmVzcyksIXQudXNlckFnZW50JiZuLnVzZXJBZ2VudCYmKHQudXNlckFnZW50PW4udXNlckFnZW50KSwibnVtYmVyIj09dHlwZW9mIG4uZXJyb3JzJiYodC5lcnJvcnM9bi5lcnJvcnMpLG4uc3RhdHVzJiYodC5zdGF0dXM9bi5zdGF0dXMpfWZ1bmN0aW9uIEcodCxuLGU9Mil7aWYoIW58fCJvYmplY3QiIT10eXBlb2Ygbnx8ZTw9MClyZXR1cm4gbjtpZih0JiYwPT09T2JqZWN0LmtleXMobikubGVuZ3RoKXJldHVybiB0O2NvbnN0IHI9ey4uLnR9O2Zvcihjb25zdCB0IGluIG4pT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG4sdCkmJihyW3RdPUcoclt0XSxuW3RdLGUtMSkpO3JldHVybiByfWNvbnN0IEo9Il9zZW50cnlTcGFuIjtmdW5jdGlvbiBZKHQsbil7bj9mdW5jdGlvbih0LG4sZSl7dHJ5e09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LG4se3ZhbHVlOmUsd3JpdGFibGU6ITAsY29uZmlndXJhYmxlOiEwfSl9Y2F0Y2goZSl7TiYmay5sb2coYEZhaWxlZCB0byBhZGQgbm9uLWVudW1lcmFibGUgcHJvcGVydHkgIiR7bn0iIHRvIG9iamVjdGAsdCl9fSh0LEosbik6ZGVsZXRlIHRbSl19ZnVuY3Rpb24geih0KXtyZXR1cm4gdFtKXX1mdW5jdGlvbiBIKCl7cmV0dXJuIEEoKX1mdW5jdGlvbiBGKCl7cmV0dXJuIEEoKS5zdWJzdHJpbmcoMTYpfWNsYXNzIFd7Y29uc3RydWN0b3IoKXt0aGlzLnQ9ITEsdGhpcy5vPVtdLHRoaXMuaT1bXSx0aGlzLnU9W10sdGhpcy5oPVtdLHRoaXMucD17fSx0aGlzLmw9e30sdGhpcy5tPXt9LHRoaXMuXz17fSx0aGlzLnY9e30sdGhpcy5TPXt0cmFjZUlkOkgoKSxzYW1wbGVSYW5kOk1hdGgucmFuZG9tKCl9fWNsb25lKCl7Y29uc3QgdD1uZXcgVztyZXR1cm4gdC51PVsuLi50aGlzLnVdLHQubD17Li4udGhpcy5sfSx0Lm09ey4uLnRoaXMubX0sdC5fPXsuLi50aGlzLl99LHRoaXMuXy5mbGFncyYmKHQuXy5mbGFncz17dmFsdWVzOlsuLi50aGlzLl8uZmxhZ3MudmFsdWVzXX0pLHQucD10aGlzLnAsdC5OPXRoaXMuTix0LlQ9dGhpcy5ULHQuQz10aGlzLkMsdC5SPXRoaXMuUix0Lmk9Wy4uLnRoaXMuaV0sdC5oPVsuLi50aGlzLmhdLHQudj17Li4udGhpcy52fSx0LlM9ey4uLnRoaXMuU30sdC5rPXRoaXMuayx0Lmo9dGhpcy5qLFkodCx6KHRoaXMpKSx0fXNldENsaWVudCh0KXt0aGlzLms9dH1zZXRMYXN0RXZlbnRJZCh0KXt0aGlzLmo9dH1nZXRDbGllbnQoKXtyZXR1cm4gdGhpcy5rfWxhc3RFdmVudElkKCl7cmV0dXJuIHRoaXMuan1hZGRTY29wZUxpc3RlbmVyKHQpe3RoaXMuby5wdXNoKHQpfWFkZEV2ZW50UHJvY2Vzc29yKHQpe3JldHVybiB0aGlzLmkucHVzaCh0KSx0aGlzfXNldFVzZXIodCl7cmV0dXJuIHRoaXMucD10fHx7ZW1haWw6dm9pZCAwLGlkOnZvaWQgMCxpcF9hZGRyZXNzOnZvaWQgMCx1c2VybmFtZTp2b2lkIDB9LHRoaXMuVCYmQih0aGlzLlQse3VzZXI6dH0pLHRoaXMuRCgpLHRoaXN9Z2V0VXNlcigpe3JldHVybiB0aGlzLnB9c2V0VGFncyh0KXtyZXR1cm4gdGhpcy5sPXsuLi50aGlzLmwsLi4udH0sdGhpcy5EKCksdGhpc31zZXRUYWcodCxuKXtyZXR1cm4gdGhpcy5sPXsuLi50aGlzLmwsW3RdOm59LHRoaXMuRCgpLHRoaXN9c2V0RXh0cmFzKHQpe3JldHVybiB0aGlzLm09ey4uLnRoaXMubSwuLi50fSx0aGlzLkQoKSx0aGlzfXNldEV4dHJhKHQsbil7cmV0dXJuIHRoaXMubT17Li4udGhpcy5tLFt0XTpufSx0aGlzLkQoKSx0aGlzfXNldEZpbmdlcnByaW50KHQpe3JldHVybiB0aGlzLlI9dCx0aGlzLkQoKSx0aGlzfXNldExldmVsKHQpe3JldHVybiB0aGlzLk49dCx0aGlzLkQoKSx0aGlzfXNldFRyYW5zYWN0aW9uTmFtZSh0KXtyZXR1cm4gdGhpcy5DPXQsdGhpcy5EKCksdGhpc31zZXRDb250ZXh0KHQsbil7cmV0dXJuIG51bGw9PT1uP2RlbGV0ZSB0aGlzLl9bdF06dGhpcy5fW3RdPW4sdGhpcy5EKCksdGhpc31zZXRTZXNzaW9uKHQpe3JldHVybiB0P3RoaXMuVD10OmRlbGV0ZSB0aGlzLlQsdGhpcy5EKCksdGhpc31nZXRTZXNzaW9uKCl7cmV0dXJuIHRoaXMuVH11cGRhdGUodCl7aWYoIXQpcmV0dXJuIHRoaXM7Y29uc3Qgbj0iZnVuY3Rpb24iPT10eXBlb2YgdD90KHRoaXMpOnQsZT1uIGluc3RhbmNlb2YgVz9uLmdldFNjb3BlRGF0YSgpOnYobik/dDp2b2lkIDAse3RhZ3M6cixleHRyYTpvLHVzZXI6cyxjb250ZXh0czppLGxldmVsOmMsZmluZ2VycHJpbnQ6dT1bXSxwcm9wYWdhdGlvbkNvbnRleHQ6YX09ZXx8e307cmV0dXJuIHRoaXMubD17Li4udGhpcy5sLC4uLnJ9LHRoaXMubT17Li4udGhpcy5tLC4uLm99LHRoaXMuXz17Li4udGhpcy5fLC4uLml9LHMmJk9iamVjdC5rZXlzKHMpLmxlbmd0aCYmKHRoaXMucD1zKSxjJiYodGhpcy5OPWMpLHUubGVuZ3RoJiYodGhpcy5SPXUpLGEmJih0aGlzLlM9YSksdGhpc31jbGVhcigpe3JldHVybiB0aGlzLnU9W10sdGhpcy5sPXt9LHRoaXMubT17fSx0aGlzLnA9e30sdGhpcy5fPXt9LHRoaXMuTj12b2lkIDAsdGhpcy5DPXZvaWQgMCx0aGlzLlI9dm9pZCAwLHRoaXMuVD12b2lkIDAsWSh0aGlzLHZvaWQgMCksdGhpcy5oPVtdLHRoaXMuc2V0UHJvcGFnYXRpb25Db250ZXh0KHt0cmFjZUlkOkgoKSxzYW1wbGVSYW5kOk1hdGgucmFuZG9tKCl9KSx0aGlzLkQoKSx0aGlzfWFkZEJyZWFkY3J1bWIodCxuKXtjb25zdCBlPSJudW1iZXIiPT10eXBlb2Ygbj9uOjEwMDtpZihlPD0wKXJldHVybiB0aGlzO2NvbnN0IHI9e3RpbWVzdGFtcDpVKCksLi4udCxtZXNzYWdlOnQubWVzc2FnZT9qKHQubWVzc2FnZSwyMDQ4KTp0Lm1lc3NhZ2V9O3JldHVybiB0aGlzLnUucHVzaChyKSx0aGlzLnUubGVuZ3RoPmUmJih0aGlzLnU9dGhpcy51LnNsaWNlKC1lKSx0aGlzLms/LnJlY29yZERyb3BwZWRFdmVudCgiYnVmZmVyX292ZXJmbG93IiwibG9nX2l0ZW0iKSksdGhpcy5EKCksdGhpc31nZXRMYXN0QnJlYWRjcnVtYigpe3JldHVybiB0aGlzLnVbdGhpcy51Lmxlbmd0aC0xXX1jbGVhckJyZWFkY3J1bWJzKCl7cmV0dXJuIHRoaXMudT1bXSx0aGlzLkQoKSx0aGlzfWFkZEF0dGFjaG1lbnQodCl7cmV0dXJuIHRoaXMuaC5wdXNoKHQpLHRoaXN9Y2xlYXJBdHRhY2htZW50cygpe3JldHVybiB0aGlzLmg9W10sdGhpc31nZXRTY29wZURhdGEoKXtyZXR1cm57YnJlYWRjcnVtYnM6dGhpcy51LGF0dGFjaG1lbnRzOnRoaXMuaCxjb250ZXh0czp0aGlzLl8sdGFnczp0aGlzLmwsZXh0cmE6dGhpcy5tLHVzZXI6dGhpcy5wLGxldmVsOnRoaXMuTixmaW5nZXJwcmludDp0aGlzLlJ8fFtdLGV2ZW50UHJvY2Vzc29yczp0aGlzLmkscHJvcGFnYXRpb25Db250ZXh0OnRoaXMuUyxzZGtQcm9jZXNzaW5nTWV0YWRhdGE6dGhpcy52LHRyYW5zYWN0aW9uTmFtZTp0aGlzLkMsc3Bhbjp6KHRoaXMpfX1zZXRTREtQcm9jZXNzaW5nTWV0YWRhdGEodCl7cmV0dXJuIHRoaXMudj1HKHRoaXMudix0LDIpLHRoaXN9c2V0UHJvcGFnYXRpb25Db250ZXh0KHQpe3JldHVybiB0aGlzLlM9dCx0aGlzfWdldFByb3BhZ2F0aW9uQ29udGV4dCgpe3JldHVybiB0aGlzLlN9Y2FwdHVyZUV4Y2VwdGlvbih0LG4pe2NvbnN0IGU9bj8uZXZlbnRfaWR8fEEoKTtpZighdGhpcy5rKXJldHVybiBrLndhcm4oIk5vIGNsaWVudCBjb25maWd1cmVkIG9uIHNjb3BlIC0gd2lsbCBub3QgY2FwdHVyZSBleGNlcHRpb24hIiksZTtjb25zdCByPW5ldyBFcnJvcigiU2VudHJ5IHN5bnRoZXRpY0V4Y2VwdGlvbiIpO3JldHVybiB0aGlzLmsuY2FwdHVyZUV4Y2VwdGlvbih0LHtvcmlnaW5hbEV4Y2VwdGlvbjp0LHN5bnRoZXRpY0V4Y2VwdGlvbjpyLC4uLm4sZXZlbnRfaWQ6ZX0sdGhpcyksZX1jYXB0dXJlTWVzc2FnZSh0LG4sZSl7Y29uc3Qgcj1lPy5ldmVudF9pZHx8QSgpO2lmKCF0aGlzLmspcmV0dXJuIGsud2FybigiTm8gY2xpZW50IGNvbmZpZ3VyZWQgb24gc2NvcGUgLSB3aWxsIG5vdCBjYXB0dXJlIG1lc3NhZ2UhIikscjtjb25zdCBvPW5ldyBFcnJvcih0KTtyZXR1cm4gdGhpcy5rLmNhcHR1cmVNZXNzYWdlKHQsbix7b3JpZ2luYWxFeGNlcHRpb246dCxzeW50aGV0aWNFeGNlcHRpb246bywuLi5lLGV2ZW50X2lkOnJ9LHRoaXMpLHJ9Y2FwdHVyZUV2ZW50KHQsbil7Y29uc3QgZT1uPy5ldmVudF9pZHx8QSgpO3JldHVybiB0aGlzLms/KHRoaXMuay5jYXB0dXJlRXZlbnQodCx7Li4ubixldmVudF9pZDplfSx0aGlzKSxlKTooay53YXJuKCJObyBjbGllbnQgY29uZmlndXJlZCBvbiBzY29wZSAtIHdpbGwgbm90IGNhcHR1cmUgZXZlbnQhIiksZSl9RCgpe3RoaXMudHx8KHRoaXMudD0hMCx0aGlzLm8uZm9yRWFjaCgodD0+e3QodGhpcyl9KSksdGhpcy50PSExKX19Y2xhc3MgS3tjb25zdHJ1Y3Rvcih0LG4pe2xldCBlLHI7ZT10fHxuZXcgVyxyPW58fG5ldyBXLHRoaXMuST1be3Njb3BlOmV9XSx0aGlzLk89cn13aXRoU2NvcGUodCl7Y29uc3Qgbj10aGlzLkEoKTtsZXQgZTt0cnl7ZT10KG4pfWNhdGNoKHQpe3Rocm93IHRoaXMuUCgpLHR9cmV0dXJuIHcoZSk/ZS50aGVuKCh0PT4odGhpcy5QKCksdCkpLCh0PT57dGhyb3cgdGhpcy5QKCksdH0pKToodGhpcy5QKCksZSl9Z2V0Q2xpZW50KCl7cmV0dXJuIHRoaXMuZ2V0U3RhY2tUb3AoKS5jbGllbnR9Z2V0U2NvcGUoKXtyZXR1cm4gdGhpcy5nZXRTdGFja1RvcCgpLnNjb3BlfWdldElzb2xhdGlvblNjb3BlKCl7cmV0dXJuIHRoaXMuT31nZXRTdGFja1RvcCgpe3JldHVybiB0aGlzLklbdGhpcy5JLmxlbmd0aC0xXX1BKCl7Y29uc3QgdD10aGlzLmdldFNjb3BlKCkuY2xvbmUoKTtyZXR1cm4gdGhpcy5JLnB1c2goe2NsaWVudDp0aGlzLmdldENsaWVudCgpLHNjb3BlOnR9KSx0fVAoKXtyZXR1cm4hKHRoaXMuSS5sZW5ndGg8PTEpJiYhIXRoaXMuSS5wb3AoKX19ZnVuY3Rpb24gVigpe2NvbnN0IHQ9bShkKCkpO3JldHVybiB0LnN0YWNrPXQuc3RhY2t8fG5ldyBLKGcoImRlZmF1bHRDdXJyZW50U2NvcGUiLCgoKT0+bmV3IFcpKSxnKCJkZWZhdWx0SXNvbGF0aW9uU2NvcGUiLCgoKT0+bmV3IFcpKSl9ZnVuY3Rpb24gWih0KXtyZXR1cm4gVigpLndpdGhTY29wZSh0KX1mdW5jdGlvbiBxKHQsbil7Y29uc3QgZT1WKCk7cmV0dXJuIGUud2l0aFNjb3BlKCgoKT0+KGUuZ2V0U3RhY2tUb3AoKS5zY29wZT10LG4odCkpKSl9ZnVuY3Rpb24gUSh0KXtyZXR1cm4gVigpLndpdGhTY29wZSgoKCk9PnQoVigpLmdldElzb2xhdGlvblNjb3BlKCkpKSl9ZnVuY3Rpb24gWCh0KXtjb25zdCBuPW0odCk7cmV0dXJuIG4uYWNzP24uYWNzOnt3aXRoSXNvbGF0aW9uU2NvcGU6USx3aXRoU2NvcGU6Wix3aXRoU2V0U2NvcGU6cSx3aXRoU2V0SXNvbGF0aW9uU2NvcGU6KHQsbik9PlEobiksZ2V0Q3VycmVudFNjb3BlOigpPT5WKCkuZ2V0U2NvcGUoKSxnZXRJc29sYXRpb25TY29wZTooKT0+VigpLmdldElzb2xhdGlvblNjb3BlKCl9fWZ1bmN0aW9uIHR0KCl7cmV0dXJuIFgoZCgpKS5nZXRDdXJyZW50U2NvcGUoKS5nZXRDbGllbnQoKX1jb25zdCBudD0ic2VudHJ5LnNvdXJjZSIsZXQ9InNlbnRyeS5zYW1wbGVfcmF0ZSIscnQ9InNlbnRyeS5vcCIsb3Q9InNlbnRyeS5vcmlnaW4iLHN0PTAsaXQ9MSxjdD0iX3NlbnRyeVNjb3BlIix1dD0iX3NlbnRyeUlzb2xhdGlvblNjb3BlIjtmdW5jdGlvbiBhdCh0KXtyZXR1cm57c2NvcGU6dFtjdF0saXNvbGF0aW9uU2NvcGU6dFt1dF19fWNvbnN0IGZ0PSJzZW50cnktIixodD0vXnNlbnRyeS0vO2Z1bmN0aW9uIHB0KHQpe2NvbnN0IG49ZnVuY3Rpb24odCl7aWYoIXR8fCFfKHQpJiYhQXJyYXkuaXNBcnJheSh0KSlyZXR1cm47aWYoQXJyYXkuaXNBcnJheSh0KSlyZXR1cm4gdC5yZWR1Y2UoKCh0LG4pPT57Y29uc3QgZT1sdChuKTtyZXR1cm4gT2JqZWN0LmVudHJpZXMoZSkuZm9yRWFjaCgoKFtuLGVdKT0+e3Rbbl09ZX0pKSx0fSkse30pO3JldHVybiBsdCh0KX0odCk7aWYoIW4pcmV0dXJuO2NvbnN0IGU9T2JqZWN0LmVudHJpZXMobikucmVkdWNlKCgodCxbbixlXSk9PntpZihuLm1hdGNoKGh0KSl7dFtuLnNsaWNlKGZ0Lmxlbmd0aCldPWV9cmV0dXJuIHR9KSx7fSk7cmV0dXJuIE9iamVjdC5rZXlzKGUpLmxlbmd0aD4wP2U6dm9pZCAwfWZ1bmN0aW9uIGx0KHQpe3JldHVybiB0LnNwbGl0KCIsIikubWFwKCh0PT50LnNwbGl0KCI9IikubWFwKCh0PT5kZWNvZGVVUklDb21wb25lbnQodC50cmltKCkpKSkpKS5yZWR1Y2UoKCh0LFtuLGVdKT0+KG4mJmUmJih0W25dPWUpLHQpKSx7fSl9Y29uc3QgZHQ9MTtmdW5jdGlvbiBtdCh0KXtjb25zdHtzcGFuSWQ6bix0cmFjZUlkOmUsaXNSZW1vdGU6cn09dC5zcGFuQ29udGV4dCgpLG89cj9uOl90KHQpLnBhcmVudF9zcGFuX2lkLHM9YXQodCkuc2NvcGU7cmV0dXJue3BhcmVudF9zcGFuX2lkOm8sc3Bhbl9pZDpyP3M/LmdldFByb3BhZ2F0aW9uQ29udGV4dCgpLnByb3BhZ2F0aW9uU3BhbklkfHxGKCk6bix0cmFjZV9pZDplfX1mdW5jdGlvbiBndCh0KXtyZXR1cm4gdCYmdC5sZW5ndGg+MD90Lm1hcCgoKHtjb250ZXh0OntzcGFuSWQ6dCx0cmFjZUlkOm4sdHJhY2VGbGFnczplLC4uLnJ9LGF0dHJpYnV0ZXM6b30pPT4oe3NwYW5faWQ6dCx0cmFjZV9pZDpuLHNhbXBsZWQ6ZT09PWR0LGF0dHJpYnV0ZXM6bywuLi5yfSkpKTp2b2lkIDB9ZnVuY3Rpb24geXQodCl7cmV0dXJuIm51bWJlciI9PXR5cGVvZiB0P2J0KHQpOkFycmF5LmlzQXJyYXkodCk/dFswXSt0WzFdLzFlOTp0IGluc3RhbmNlb2YgRGF0ZT9idCh0LmdldFRpbWUoKSk6TSgpfWZ1bmN0aW9uIGJ0KHQpe3JldHVybiB0Pjk5OTk5OTk5OTk/dC8xZTM6dH1mdW5jdGlvbiBfdCh0KXtpZihmdW5jdGlvbih0KXtyZXR1cm4iZnVuY3Rpb24iPT10eXBlb2YgdC5nZXRTcGFuSlNPTn0odCkpcmV0dXJuIHQuZ2V0U3BhbkpTT04oKTtjb25zdHtzcGFuSWQ6bix0cmFjZUlkOmV9PXQuc3BhbkNvbnRleHQoKTtpZihmdW5jdGlvbih0KXtjb25zdCBuPXQ7cmV0dXJuISEobi5hdHRyaWJ1dGVzJiZuLnN0YXJ0VGltZSYmbi5uYW1lJiZuLmVuZFRpbWUmJm4uc3RhdHVzKX0odCkpe2NvbnN0e2F0dHJpYnV0ZXM6cixzdGFydFRpbWU6byxuYW1lOnMsZW5kVGltZTppLHBhcmVudFNwYW5JZDpjLHN0YXR1czp1LGxpbmtzOmF9PXQ7cmV0dXJue3NwYW5faWQ6bix0cmFjZV9pZDplLGRhdGE6cixkZXNjcmlwdGlvbjpzLHBhcmVudF9zcGFuX2lkOmMsc3RhcnRfdGltZXN0YW1wOnl0KG8pLHRpbWVzdGFtcDp5dChpKXx8dm9pZCAwLHN0YXR1czp2dCh1KSxvcDpyW3J0XSxvcmlnaW46cltvdF0sbGlua3M6Z3QoYSl9fXJldHVybntzcGFuX2lkOm4sdHJhY2VfaWQ6ZSxzdGFydF90aW1lc3RhbXA6MCxkYXRhOnt9fX1mdW5jdGlvbiB2dCh0KXtpZih0JiZ0LmNvZGUhPT1zdClyZXR1cm4gdC5jb2RlPT09aXQ/Im9rIjp0Lm1lc3NhZ2V8fCJ1bmtub3duX2Vycm9yIn1jb25zdCB3dD0iX3NlbnRyeVJvb3RTcGFuIjtmdW5jdGlvbiBTdCh0KXtyZXR1cm4gdFt3dF18fHR9Y29uc3QgJHQ9NTAsRXQ9Ij8iLHh0PS9jYXB0dXJlTWVzc2FnZXxjYXB0dXJlRXhjZXB0aW9uLztmdW5jdGlvbiBOdCh0KXtyZXR1cm4gdFt0Lmxlbmd0aC0xXXx8e319Y29uc3QgVHQ9Ijxhbm9ueW1vdXM+Ijtjb25zdCBDdD0icHJvZHVjdGlvbiIsUnQ9Il9mcm96ZW5Ec2MiO2Z1bmN0aW9uIGt0KHQpe2NvbnN0IG49dHQoKTtpZighbilyZXR1cm57fTtjb25zdCBlPVN0KHQpLHI9X3QoZSksbz1yLmRhdGEscz1lLnNwYW5Db250ZXh0KCkudHJhY2VTdGF0ZSxpPXM/LmdldCgic2VudHJ5LnNhbXBsZV9yYXRlIik/P29bZXRdO2Z1bmN0aW9uIGModCl7cmV0dXJuIm51bWJlciIhPXR5cGVvZiBpJiYic3RyaW5nIiE9dHlwZW9mIGl8fCh0LnNhbXBsZV9yYXRlPWAke2l9YCksdH1jb25zdCB1PWVbUnRdO2lmKHUpcmV0dXJuIGModSk7Y29uc3QgYT1zPy5nZXQoInNlbnRyeS5kc2MiKSxmPWEmJnB0KGEpO2lmKGYpcmV0dXJuIGMoZik7Y29uc3QgaD1mdW5jdGlvbih0LG4pe2NvbnN0IGU9bi5nZXRPcHRpb25zKCkse3B1YmxpY0tleTpyfT1uLmdldERzbigpfHx7fSxvPXtlbnZpcm9ubWVudDplLmVudmlyb25tZW50fHxDdCxyZWxlYXNlOmUucmVsZWFzZSxwdWJsaWNfa2V5OnIsdHJhY2VfaWQ6dH07cmV0dXJuIG4uZW1pdCgiY3JlYXRlRHNjIixvKSxvfSh0LnNwYW5Db250ZXh0KCkudHJhY2VJZCxuKSxwPW9bbnRdLGw9ci5kZXNjcmlwdGlvbjtyZXR1cm4idXJsIiE9PXAmJmwmJihoLnRyYW5zYWN0aW9uPWwpLGZ1bmN0aW9uKHQpe2lmKCJib29sZWFuIj09dHlwZW9mIF9fU0VOVFJZX1RSQUNJTkdfXyYmIV9fU0VOVFJZX1RSQUNJTkdfXylyZXR1cm4hMTtjb25zdCBuPXR8fHR0KCk/LmdldE9wdGlvbnMoKTtyZXR1cm4hKCFufHxudWxsPT1uLnRyYWNlc1NhbXBsZVJhdGUmJiFuLnRyYWNlc1NhbXBsZXIpfSgpJiYoaC5zYW1wbGVkPVN0cmluZyhmdW5jdGlvbih0KXtjb25zdHt0cmFjZUZsYWdzOm59PXQuc3BhbkNvbnRleHQoKTtyZXR1cm4gbj09PWR0fShlKSksaC5zYW1wbGVfcmFuZD1zPy5nZXQoInNlbnRyeS5zYW1wbGVfcmFuZCIpPz9hdChlKS5zY29wZT8uZ2V0UHJvcGFnYXRpb25Db250ZXh0KCkuc2FtcGxlUmFuZC50b1N0cmluZygpKSxjKGgpLG4uZW1pdCgiY3JlYXRlRHNjIixoLGUpLGh9ZnVuY3Rpb24ganQodCxuPSExKXtjb25zdHtob3N0OmUscGF0aDpyLHBhc3M6byxwb3J0OnMscHJvamVjdElkOmkscHJvdG9jb2w6YyxwdWJsaWNLZXk6dX09dDtyZXR1cm5gJHtjfTovLyR7dX0ke24mJm8/YDoke299YDoiIn1AJHtlfSR7cz9gOiR7c31gOiIifS8ke3I/YCR7cn0vYDpyfSR7aX1gfWZ1bmN0aW9uIER0KHQsbj0xMDAsZT0xLzApe3RyeXtyZXR1cm4gSXQoIiIsdCxuLGUpfWNhdGNoKHQpe3JldHVybntFUlJPUjpgKipub24tc2VyaWFsaXphYmxlKiogKCR7dH0pYH19fWZ1bmN0aW9uIEl0KHQsbixlPTEvMCxyPTEvMCxvPWZ1bmN0aW9uKCl7Y29uc3QgdD1uZXcgV2Vha1NldDtmdW5jdGlvbiBuKG4pe3JldHVybiEhdC5oYXMobil8fCh0LmFkZChuKSwhMSl9ZnVuY3Rpb24gZShuKXt0LmRlbGV0ZShuKX1yZXR1cm5bbixlXX0oKSl7Y29uc3RbcyxpXT1vO2lmKG51bGw9PW58fFsiYm9vbGVhbiIsInN0cmluZyJdLmluY2x1ZGVzKHR5cGVvZiBuKXx8Im51bWJlciI9PXR5cGVvZiBuJiZOdW1iZXIuaXNGaW5pdGUobikpcmV0dXJuIG47Y29uc3QgYz1mdW5jdGlvbih0LG4pe3RyeXtpZigiZG9tYWluIj09PXQmJm4mJiJvYmplY3QiPT10eXBlb2YgbiYmbi5VKXJldHVybiJbRG9tYWluXSI7aWYoImRvbWFpbkVtaXR0ZXIiPT09dClyZXR1cm4iW0RvbWFpbkVtaXR0ZXJdIjtpZigidW5kZWZpbmVkIiE9dHlwZW9mIGdsb2JhbCYmbj09PWdsb2JhbClyZXR1cm4iW0dsb2JhbF0iO2lmKCJ1bmRlZmluZWQiIT10eXBlb2Ygd2luZG93JiZuPT09d2luZG93KXJldHVybiJbV2luZG93XSI7aWYoInVuZGVmaW5lZCIhPXR5cGVvZiBkb2N1bWVudCYmbj09PWRvY3VtZW50KXJldHVybiJbRG9jdW1lbnRdIjtpZigib2JqZWN0Ij09dHlwZW9mKGU9bikmJm51bGwhPT1lJiYoZS5fX2lzVnVlfHxlLk0pKXJldHVybiJbVnVlVmlld01vZGVsXSI7aWYoZnVuY3Rpb24odCl7cmV0dXJuIHYodCkmJiJuYXRpdmVFdmVudCJpbiB0JiYicHJldmVudERlZmF1bHQiaW4gdCYmInN0b3BQcm9wYWdhdGlvbiJpbiB0fShuKSlyZXR1cm4iW1N5bnRoZXRpY0V2ZW50XSI7aWYoIm51bWJlciI9PXR5cGVvZiBuJiYhTnVtYmVyLmlzRmluaXRlKG4pKXJldHVybmBbJHtufV1gO2lmKCJmdW5jdGlvbiI9PXR5cGVvZiBuKXJldHVybmBbRnVuY3Rpb246ICR7ZnVuY3Rpb24odCl7dHJ5e3JldHVybiB0JiYiZnVuY3Rpb24iPT10eXBlb2YgdCYmdC5uYW1lfHxUdH1jYXRjaCh0KXtyZXR1cm4gVHR9fShuKX1dYDtpZigic3ltYm9sIj09dHlwZW9mIG4pcmV0dXJuYFske1N0cmluZyhuKX1dYDtpZigiYmlnaW50Ij09dHlwZW9mIG4pcmV0dXJuYFtCaWdJbnQ6ICR7U3RyaW5nKG4pfV1gO2NvbnN0IHI9ZnVuY3Rpb24odCl7Y29uc3Qgbj1PYmplY3QuZ2V0UHJvdG90eXBlT2YodCk7cmV0dXJuIG4/LmNvbnN0cnVjdG9yP24uY29uc3RydWN0b3IubmFtZToibnVsbCBwcm90b3R5cGUifShuKTtyZXR1cm4vXkhUTUwoXHcqKUVsZW1lbnQkLy50ZXN0KHIpP2BbSFRNTEVsZW1lbnQ6ICR7cn1dYDpgW29iamVjdCAke3J9XWB9Y2F0Y2godCl7cmV0dXJuYCoqbm9uLXNlcmlhbGl6YWJsZSoqICgke3R9KWB9dmFyIGV9KHQsbik7aWYoIWMuc3RhcnRzV2l0aCgiW29iamVjdCAiKSlyZXR1cm4gYztpZihuLl9fc2VudHJ5X3NraXBfbm9ybWFsaXphdGlvbl9fKXJldHVybiBuO2NvbnN0IHU9Im51bWJlciI9PXR5cGVvZiBuLl9fc2VudHJ5X292ZXJyaWRlX25vcm1hbGl6YXRpb25fZGVwdGhfXz9uLl9fc2VudHJ5X292ZXJyaWRlX25vcm1hbGl6YXRpb25fZGVwdGhfXzplO2lmKDA9PT11KXJldHVybiBjLnJlcGxhY2UoIm9iamVjdCAiLCIiKTtpZihzKG4pKXJldHVybiJbQ2lyY3VsYXIgfl0iO2NvbnN0IGE9bjtpZihhJiYiZnVuY3Rpb24iPT10eXBlb2YgYS50b0pTT04pdHJ5e3JldHVybiBJdCgiIixhLnRvSlNPTigpLHUtMSxyLG8pfWNhdGNoKHQpe31jb25zdCBmPUFycmF5LmlzQXJyYXkobik/W106e307bGV0IGg9MDtjb25zdCBwPUQobik7Zm9yKGNvbnN0IHQgaW4gcCl7aWYoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChwLHQpKWNvbnRpbnVlO2lmKGg+PXIpe2ZbdF09IltNYXhQcm9wZXJ0aWVzIH5dIjticmVha31jb25zdCBuPXBbdF07Zlt0XT1JdCh0LG4sdS0xLHIsbyksaCsrfXJldHVybiBpKG4pLGZ9ZnVuY3Rpb24gT3QodCxuKXtjb25zdCBlPW4ucmVwbGFjZSgvXFwvZywiLyIpLnJlcGxhY2UoL1t8XFx7fSgpW1xdXiQrKj8uXS9nLCJcXCQmIik7bGV0IHI9dDt0cnl7cj1kZWNvZGVVUkkodCl9Y2F0Y2godCl7fXJldHVybiByLnJlcGxhY2UoL1xcL2csIi8iKS5yZXBsYWNlKC93ZWJwYWNrOlwvPy9nLCIiKS5yZXBsYWNlKG5ldyBSZWdFeHAoYChmaWxlOi8vKT8vKiR7ZX0vKmAsImlnIiksImFwcDovLy8iKX1mdW5jdGlvbiBBdCh0LG49W10pe3JldHVyblt0LG5dfWZ1bmN0aW9uIFB0KHQsbil7Y29uc3QgZT10WzFdO2Zvcihjb25zdCB0IG9mIGUpe2lmKG4odCx0WzBdLnR5cGUpKXJldHVybiEwfXJldHVybiExfWZ1bmN0aW9uIFV0KHQpe2NvbnN0IG49bShsKTtyZXR1cm4gbi5lbmNvZGVQb2x5ZmlsbD9uLmVuY29kZVBvbHlmaWxsKHQpOihuZXcgVGV4dEVuY29kZXIpLmVuY29kZSh0KX1mdW5jdGlvbiBNdCh0KXtjb25zdFtuLGVdPXQ7bGV0IHI9SlNPTi5zdHJpbmdpZnkobik7ZnVuY3Rpb24gbyh0KXsic3RyaW5nIj09dHlwZW9mIHI/cj0ic3RyaW5nIj09dHlwZW9mIHQ/cit0OltVdChyKSx0XTpyLnB1c2goInN0cmluZyI9PXR5cGVvZiB0P1V0KHQpOnQpfWZvcihjb25zdCB0IG9mIGUpe2NvbnN0W24sZV09dDtpZihvKGBcbiR7SlNPTi5zdHJpbmdpZnkobil9XG5gKSwic3RyaW5nIj09dHlwZW9mIGV8fGUgaW5zdGFuY2VvZiBVaW50OEFycmF5KW8oZSk7ZWxzZXtsZXQgdDt0cnl7dD1KU09OLnN0cmluZ2lmeShlKX1jYXRjaChuKXt0PUpTT04uc3RyaW5naWZ5KER0KGUpKX1vKHQpfX1yZXR1cm4ic3RyaW5nIj09dHlwZW9mIHI/cjpmdW5jdGlvbih0KXtjb25zdCBuPXQucmVkdWNlKCgodCxuKT0+dCtuLmxlbmd0aCksMCksZT1uZXcgVWludDhBcnJheShuKTtsZXQgcj0wO2Zvcihjb25zdCBuIG9mIHQpZS5zZXQobixyKSxyKz1uLmxlbmd0aDtyZXR1cm4gZX0ocil9Y29uc3QgTHQ9e3Nlc3Npb246InNlc3Npb24iLHNlc3Npb25zOiJzZXNzaW9uIixhdHRhY2htZW50OiJhdHRhY2htZW50Iix0cmFuc2FjdGlvbjoidHJhbnNhY3Rpb24iLGV2ZW50OiJlcnJvciIsY2xpZW50X3JlcG9ydDoiaW50ZXJuYWwiLHVzZXJfcmVwb3J0OiJkZWZhdWx0Iixwcm9maWxlOiJwcm9maWxlIixwcm9maWxlX2NodW5rOiJwcm9maWxlIixyZXBsYXlfZXZlbnQ6InJlcGxheSIscmVwbGF5X3JlY29yZGluZzoicmVwbGF5IixjaGVja19pbjoibW9uaXRvciIsZmVlZGJhY2s6ImZlZWRiYWNrIixzcGFuOiJzcGFuIixyYXdfc2VjdXJpdHk6InNlY3VyaXR5IixvdGVsX2xvZzoibG9nX2l0ZW0ifTtmdW5jdGlvbiBCdCh0KXtpZighdD8uc2RrKXJldHVybjtjb25zdHtuYW1lOm4sdmVyc2lvbjplfT10LnNkaztyZXR1cm57bmFtZTpuLHZlcnNpb246ZX19ZnVuY3Rpb24gR3QodCxuLGUscil7Y29uc3Qgbz1CdChlKSxzPXQudHlwZSYmInJlcGxheV9ldmVudCIhPT10LnR5cGU/dC50eXBlOiJldmVudCI7IWZ1bmN0aW9uKHQsbil7biYmKHQuc2RrPXQuc2RrfHx7fSx0LnNkay5uYW1lPXQuc2RrLm5hbWV8fG4ubmFtZSx0LnNkay52ZXJzaW9uPXQuc2RrLnZlcnNpb258fG4udmVyc2lvbix0LnNkay5pbnRlZ3JhdGlvbnM9Wy4uLnQuc2RrLmludGVncmF0aW9uc3x8W10sLi4ubi5pbnRlZ3JhdGlvbnN8fFtdXSx0LnNkay5wYWNrYWdlcz1bLi4udC5zZGsucGFja2FnZXN8fFtdLC4uLm4ucGFja2FnZXN8fFtdXSl9KHQsZT8uc2RrKTtjb25zdCBpPWZ1bmN0aW9uKHQsbixlLHIpe2NvbnN0IG89dC5zZGtQcm9jZXNzaW5nTWV0YWRhdGE/LmR5bmFtaWNTYW1wbGluZ0NvbnRleHQ7cmV0dXJue2V2ZW50X2lkOnQuZXZlbnRfaWQsc2VudF9hdDoobmV3IERhdGUpLnRvSVNPU3RyaW5nKCksLi4ubiYme3NkazpufSwuLi4hIWUmJnImJntkc246anQocil9LC4uLm8mJnt0cmFjZTpvfX19KHQsbyxyLG4pO2RlbGV0ZSB0LnNka1Byb2Nlc3NpbmdNZXRhZGF0YTtyZXR1cm4gQXQoaSxbW3t0eXBlOnN9LHRdXSl9Y29uc3QgSnQ9Il9fU0VOVFJZX1NVUFBSRVNTX1RSQUNJTkdfXyI7ZnVuY3Rpb24gWXQodCl7Y29uc3Qgbj1YKGQoKSk7cmV0dXJuIG4uc3VwcHJlc3NUcmFjaW5nP24uc3VwcHJlc3NUcmFjaW5nKHQpOmZ1bmN0aW9uKC4uLnQpe2NvbnN0IG49WChkKCkpO2lmKDI9PT10Lmxlbmd0aCl7Y29uc3RbZSxyXT10O3JldHVybiBlP24ud2l0aFNldFNjb3BlKGUscik6bi53aXRoU2NvcGUocil9cmV0dXJuIG4ud2l0aFNjb3BlKHRbMF0pfSgobj0+KG4uc2V0U0RLUHJvY2Vzc2luZ01ldGFkYXRhKHtbSnRdOiEwfSksdCgpKSkpfXZhciB6dDtmdW5jdGlvbiBIdCh0KXtyZXR1cm4gbmV3IEZ0KChuPT57bih0KX0pKX0hZnVuY3Rpb24odCl7dFt0LlBFTkRJTkc9MF09IlBFTkRJTkciO3RbdC5SRVNPTFZFRD0xXT0iUkVTT0xWRUQiO3RbdC5SRUpFQ1RFRD0yXT0iUkVKRUNURUQifSh6dHx8KHp0PXt9KSk7Y2xhc3MgRnR7Y29uc3RydWN0b3IodCl7dGhpcy5MPXp0LlBFTkRJTkcsdGhpcy5CPVtdLHRoaXMuRyh0KX10aGVuKHQsbil7cmV0dXJuIG5ldyBGdCgoKGUscik9Pnt0aGlzLkIucHVzaChbITEsbj0+e2lmKHQpdHJ5e2UodChuKSl9Y2F0Y2godCl7cih0KX1lbHNlIGUobil9LHQ9PntpZihuKXRyeXtlKG4odCkpfWNhdGNoKHQpe3IodCl9ZWxzZSByKHQpfV0pLHRoaXMuSigpfSkpfWNhdGNoKHQpe3JldHVybiB0aGlzLnRoZW4oKHQ9PnQpLHQpfWZpbmFsbHkodCl7cmV0dXJuIG5ldyBGdCgoKG4sZSk9PntsZXQgcixvO3JldHVybiB0aGlzLnRoZW4oKG49PntvPSExLHI9bix0JiZ0KCl9KSwobj0+e289ITAscj1uLHQmJnQoKX0pKS50aGVuKCgoKT0+e28/ZShyKTpuKHIpfSkpfSkpfUooKXtpZih0aGlzLkw9PT16dC5QRU5ESU5HKXJldHVybjtjb25zdCB0PXRoaXMuQi5zbGljZSgpO3RoaXMuQj1bXSx0LmZvckVhY2goKHQ9Pnt0WzBdfHwodGhpcy5MPT09enQuUkVTT0xWRUQmJnRbMV0odGhpcy5ZKSx0aGlzLkw9PT16dC5SRUpFQ1RFRCYmdFsyXSh0aGlzLlkpLHRbMF09ITApfSkpfUcodCl7Y29uc3Qgbj0odCxuKT0+e3RoaXMuTD09PXp0LlBFTkRJTkcmJih3KG4pP24udGhlbihlLHIpOih0aGlzLkw9dCx0aGlzLlk9bix0aGlzLkooKSkpfSxlPXQ9PntuKHp0LlJFU09MVkVELHQpfSxyPXQ9PntuKHp0LlJFSkVDVEVELHQpfTt0cnl7dChlLHIpfWNhdGNoKHQpe3IodCl9fX1mdW5jdGlvbiBXdCh0LG4pe2NvbnN0e2ZpbmdlcnByaW50OmUsc3BhbjpyLGJyZWFkY3J1bWJzOm8sc2RrUHJvY2Vzc2luZ01ldGFkYXRhOnN9PW47IWZ1bmN0aW9uKHQsbil7Y29uc3R7ZXh0cmE6ZSx0YWdzOnIsdXNlcjpvLGNvbnRleHRzOnMsbGV2ZWw6aSx0cmFuc2FjdGlvbk5hbWU6Y309bjtPYmplY3Qua2V5cyhlKS5sZW5ndGgmJih0LmV4dHJhPXsuLi5lLC4uLnQuZXh0cmF9KTtPYmplY3Qua2V5cyhyKS5sZW5ndGgmJih0LnRhZ3M9ey4uLnIsLi4udC50YWdzfSk7T2JqZWN0LmtleXMobykubGVuZ3RoJiYodC51c2VyPXsuLi5vLC4uLnQudXNlcn0pO09iamVjdC5rZXlzKHMpLmxlbmd0aCYmKHQuY29udGV4dHM9ey4uLnMsLi4udC5jb250ZXh0c30pO2kmJih0LmxldmVsPWkpO2MmJiJ0cmFuc2FjdGlvbiIhPT10LnR5cGUmJih0LnRyYW5zYWN0aW9uPWMpfSh0LG4pLHImJmZ1bmN0aW9uKHQsbil7dC5jb250ZXh0cz17dHJhY2U6bXQobiksLi4udC5jb250ZXh0c30sdC5zZGtQcm9jZXNzaW5nTWV0YWRhdGE9e2R5bmFtaWNTYW1wbGluZ0NvbnRleHQ6a3QobiksLi4udC5zZGtQcm9jZXNzaW5nTWV0YWRhdGF9O2NvbnN0IGU9U3Qobikscj1fdChlKS5kZXNjcmlwdGlvbjtyJiYhdC50cmFuc2FjdGlvbiYmInRyYW5zYWN0aW9uIj09PXQudHlwZSYmKHQudHJhbnNhY3Rpb249cil9KHQsciksZnVuY3Rpb24odCxuKXt0LmZpbmdlcnByaW50PXQuZmluZ2VycHJpbnQ/QXJyYXkuaXNBcnJheSh0LmZpbmdlcnByaW50KT90LmZpbmdlcnByaW50Olt0LmZpbmdlcnByaW50XTpbXSxuJiYodC5maW5nZXJwcmludD10LmZpbmdlcnByaW50LmNvbmNhdChuKSk7dC5maW5nZXJwcmludC5sZW5ndGh8fGRlbGV0ZSB0LmZpbmdlcnByaW50fSh0LGUpLGZ1bmN0aW9uKHQsbil7Y29uc3QgZT1bLi4udC5icmVhZGNydW1ic3x8W10sLi4ubl07dC5icmVhZGNydW1icz1lLmxlbmd0aD9lOnZvaWQgMH0odCxvKSxmdW5jdGlvbih0LG4pe3Quc2RrUHJvY2Vzc2luZ01ldGFkYXRhPXsuLi50LnNka1Byb2Nlc3NpbmdNZXRhZGF0YSwuLi5ufX0odCxzKX1jb25zdCBLdD0iNyI7Y29uc3QgVnQ9U3ltYm9sLmZvcigiU2VudHJ5QnVmZmVyRnVsbEVycm9yIik7ZnVuY3Rpb24gWnQodCl7Y29uc3Qgbj1bXTtmdW5jdGlvbiBlKHQpe3JldHVybiBuLnNwbGljZShuLmluZGV4T2YodCksMSlbMF18fFByb21pc2UucmVzb2x2ZSh2b2lkIDApfXJldHVybnskOm4sYWRkOmZ1bmN0aW9uKHIpe2lmKCEodm9pZCAwPT09dHx8bi5sZW5ndGg8dCkpcmV0dXJuIG89VnQsbmV3IEZ0KCgodCxuKT0+e24obyl9KSk7dmFyIG87Y29uc3Qgcz1yKCk7cmV0dXJuLTE9PT1uLmluZGV4T2YocykmJm4ucHVzaChzKSxzLnRoZW4oKCgpPT5lKHMpKSkudGhlbihudWxsLCgoKT0+ZShzKS50aGVuKG51bGwsKCgpPT57fSkpKSksc30sZHJhaW46ZnVuY3Rpb24odCl7cmV0dXJuIG5ldyBGdCgoKGUscik9PntsZXQgbz1uLmxlbmd0aDtpZighbylyZXR1cm4gZSghMCk7Y29uc3Qgcz1zZXRUaW1lb3V0KCgoKT0+e3QmJnQ+MCYmZSghMSl9KSx0KTtuLmZvckVhY2goKHQ9PntIdCh0KS50aGVuKCgoKT0+ey0tb3x8KGNsZWFyVGltZW91dChzKSxlKCEwKSl9KSxyKX0pKX0pKX19fWNvbnN0IHF0PTZlNDtmdW5jdGlvbiBRdCh0LHtzdGF0dXNDb2RlOm4saGVhZGVyczplfSxyPURhdGUubm93KCkpe2NvbnN0IG89ey4uLnR9LHM9ZT8uWyJ4LXNlbnRyeS1yYXRlLWxpbWl0cyJdLGk9ZT8uWyJyZXRyeS1hZnRlciJdO2lmKHMpZm9yKGNvbnN0IHQgb2Ygcy50cmltKCkuc3BsaXQoIiwiKSl7Y29uc3RbbixlLCwsc109dC5zcGxpdCgiOiIsNSksaT1wYXJzZUludChuLDEwKSxjPTFlMyooaXNOYU4oaSk/NjA6aSk7aWYoZSlmb3IoY29uc3QgdCBvZiBlLnNwbGl0KCI7IikpIm1ldHJpY19idWNrZXQiPT09dCYmcyYmIXMuc3BsaXQoIjsiKS5pbmNsdWRlcygiY3VzdG9tIil8fChvW3RdPXIrYyk7ZWxzZSBvLmFsbD1yK2N9ZWxzZSBpP28uYWxsPXIrZnVuY3Rpb24odCxuPURhdGUubm93KCkpe2NvbnN0IGU9cGFyc2VJbnQoYCR7dH1gLDEwKTtpZighaXNOYU4oZSkpcmV0dXJuIDFlMyplO2NvbnN0IHI9RGF0ZS5wYXJzZShgJHt0fWApO3JldHVybiBpc05hTihyKT9xdDpyLW59KGkscik6NDI5PT09biYmKG8uYWxsPXIrNmU0KTtyZXR1cm4gb31jb25zdCBYdD02NDtmdW5jdGlvbiB0bih0LG4sZT1adCh0LmJ1ZmZlclNpemV8fFh0KSl7bGV0IHI9e307cmV0dXJue3NlbmQ6ZnVuY3Rpb24odCl7Y29uc3Qgbz1bXTtpZihQdCh0LCgodCxuKT0+e2NvbnN0IGU9ZnVuY3Rpb24odCl7cmV0dXJuIEx0W3RdfShuKTsoZnVuY3Rpb24odCxuLGU9RGF0ZS5ub3coKSl7cmV0dXJuIGZ1bmN0aW9uKHQsbil7cmV0dXJuIHRbbl18fHQuYWxsfHwwfSh0LG4pPmV9KShyLGUpfHxvLnB1c2godCl9KSksMD09PW8ubGVuZ3RoKXJldHVybiBIdCh7fSk7Y29uc3Qgcz1BdCh0WzBdLG8pLGk9dD0+e1B0KHMsKCh0LG4pPT57fSkpfTtyZXR1cm4gZS5hZGQoKCgpPT5uKHtib2R5Ok10KHMpfSkudGhlbigodD0+KHZvaWQgMCE9PXQuc3RhdHVzQ29kZSYmKHQuc3RhdHVzQ29kZTwyMDB8fHQuc3RhdHVzQ29kZT49MzAwKSYmaCYmay53YXJuKGBTZW50cnkgcmVzcG9uZGVkIHdpdGggc3RhdHVzIGNvZGUgJHt0LnN0YXR1c0NvZGV9IHRvIHNlbnQgZXZlbnQuYCkscj1RdChyLHQpLHQpKSwodD0+e3Rocm93IGkoKSxoJiZrLmVycm9yKCJFbmNvdW50ZXJlZCBlcnJvciBydW5uaW5nIHRyYW5zcG9ydCByZXF1ZXN0OiIsdCksdH0pKSkpLnRoZW4oKHQ9PnQpLCh0PT57aWYodD09PVZ0KXJldHVybiBoJiZrLmVycm9yKCJTa2lwcGVkIHNlbmRpbmcgZXZlbnQgYmVjYXVzZSBidWZmZXIgaXMgZnVsbC4iKSxpKCksSHQoe30pO3Rocm93IHR9KSl9LGZsdXNoOnQ9PmUuZHJhaW4odCl9fWNvbnN0IG5uPS9eKFxTKzpcXHxcLz8pKFtcc1xTXSo/KSgoPzpcLnsxLDJ9fFteL1xcXSs/fCkoXC5bXi4vXFxdKnwpKSg/OlsvXFxdKikkLztmdW5jdGlvbiBlbih0KXtjb25zdCBuPWZ1bmN0aW9uKHQpe2NvbnN0IG49dC5sZW5ndGg+MTAyND9gPHRydW5jYXRlZD4ke3Quc2xpY2UoLTEwMjQpfWA6dCxlPW5uLmV4ZWMobik7cmV0dXJuIGU/ZS5zbGljZSgxKTpbXX0odCksZT1uWzBdfHwiIjtsZXQgcj1uWzFdO3JldHVybiBlfHxyPyhyJiYocj1yLnNsaWNlKDAsci5sZW5ndGgtMSkpLGUrcik6Ii4ifWZ1bmN0aW9uIHJuKHQsbj0hMSl7cmV0dXJuIShufHx0JiYhdC5zdGFydHNXaXRoKCIvIikmJiF0Lm1hdGNoKC9eW0EtWl06LykmJiF0LnN0YXJ0c1dpdGgoIi4iKSYmIXQubWF0Y2goL15bYS16QS1aXShbYS16QS1aMC05LlwtK10pKjpcL1wvLykpJiZ2b2lkIDAhPT10JiYhdC5pbmNsdWRlcygibm9kZV9tb2R1bGVzLyIpfWNvbnN0IG9uPVN5bWJvbCgiQWdlbnRCYXNlSW50ZXJuYWxTdGF0ZSIpO2NsYXNzIHNuIGV4dGVuZHMgcy5BZ2VudHtjb25zdHJ1Y3Rvcih0KXtzdXBlcih0KSx0aGlzW29uXT17fX1pc1NlY3VyZUVuZHBvaW50KHQpe2lmKHQpe2lmKCJib29sZWFuIj09dHlwZW9mIHQuc2VjdXJlRW5kcG9pbnQpcmV0dXJuIHQuc2VjdXJlRW5kcG9pbnQ7aWYoInN0cmluZyI9PXR5cGVvZiB0LnByb3RvY29sKXJldHVybiJodHRwczoiPT09dC5wcm90b2NvbH1jb25zdHtzdGFjazpufT1uZXcgRXJyb3I7cmV0dXJuInN0cmluZyI9PXR5cGVvZiBuJiZuLnNwbGl0KCJcbiIpLnNvbWUoKHQ9Pi0xIT09dC5pbmRleE9mKCIoaHR0cHMuanM6Iil8fC0xIT09dC5pbmRleE9mKCJub2RlOmh0dHBzOiIpKSl9Y3JlYXRlU29ja2V0KHQsbixlKXtjb25zdCByPXsuLi5uLHNlY3VyZUVuZHBvaW50OnRoaXMuaXNTZWN1cmVFbmRwb2ludChuKX07UHJvbWlzZS5yZXNvbHZlKCkudGhlbigoKCk9PnRoaXMuY29ubmVjdCh0LHIpKSkudGhlbigobz0+e2lmKG8gaW5zdGFuY2VvZiBzLkFnZW50KXJldHVybiBvLmFkZFJlcXVlc3QodCxyKTt0aGlzW29uXS5jdXJyZW50U29ja2V0PW8sc3VwZXIuY3JlYXRlU29ja2V0KHQsbixlKX0pLGUpfWNyZWF0ZUNvbm5lY3Rpb24oKXtjb25zdCB0PXRoaXNbb25dLmN1cnJlbnRTb2NrZXQ7aWYodGhpc1tvbl0uY3VycmVudFNvY2tldD12b2lkIDAsIXQpdGhyb3cgbmV3IEVycm9yKCJObyBzb2NrZXQgd2FzIHJldHVybmVkIGluIHRoZSBgY29ubmVjdCgpYCBmdW5jdGlvbiIpO3JldHVybiB0fWdldCBkZWZhdWx0UG9ydCgpe3JldHVybiB0aGlzW29uXS5kZWZhdWx0UG9ydD8/KCJodHRwczoiPT09dGhpcy5wcm90b2NvbD80NDM6ODApfXNldCBkZWZhdWx0UG9ydCh0KXt0aGlzW29uXSYmKHRoaXNbb25dLmRlZmF1bHRQb3J0PXQpfWdldCBwcm90b2NvbCgpe3JldHVybiB0aGlzW29uXS5wcm90b2NvbD8/KHRoaXMuaXNTZWN1cmVFbmRwb2ludCgpPyJodHRwczoiOiJodHRwOiIpfXNldCBwcm90b2NvbCh0KXt0aGlzW29uXSYmKHRoaXNbb25dLnByb3RvY29sPXQpfX1mdW5jdGlvbiBjbiguLi50KXtrLmxvZygiW2h0dHBzLXByb3h5LWFnZW50OnBhcnNlLXByb3h5LXJlc3BvbnNlXSIsLi4udCl9ZnVuY3Rpb24gdW4odCl7cmV0dXJuIG5ldyBQcm9taXNlKCgobixlKT0+e2xldCByPTA7Y29uc3Qgbz1bXTtmdW5jdGlvbiBzKCl7Y29uc3QgYz10LnJlYWQoKTtjP2Z1bmN0aW9uKGMpe28ucHVzaChjKSxyKz1jLmxlbmd0aDtjb25zdCB1PUJ1ZmZlci5jb25jYXQobyxyKSxhPXUuaW5kZXhPZigiXHJcblxyXG4iKTtpZigtMT09PWEpcmV0dXJuIGNuKCJoYXZlIG5vdCByZWNlaXZlZCBlbmQgb2YgSFRUUCBoZWFkZXJzIHlldC4uLiIpLHZvaWQgcygpO2NvbnN0IGY9dS5zdWJhcnJheSgwLGEpLnRvU3RyaW5nKCJhc2NpaSIpLnNwbGl0KCJcclxuIiksaD1mLnNoaWZ0KCk7aWYoIWgpcmV0dXJuIHQuZGVzdHJveSgpLGUobmV3IEVycm9yKCJObyBoZWFkZXIgcmVjZWl2ZWQgZnJvbSBwcm94eSBDT05ORUNUIHJlc3BvbnNlIikpO2NvbnN0IHA9aC5zcGxpdCgiICIpLGw9KyhwWzFdfHwwKSxkPXAuc2xpY2UoMikuam9pbigiICIpLG09e307Zm9yKGNvbnN0IG4gb2YgZil7aWYoIW4pY29udGludWU7Y29uc3Qgcj1uLmluZGV4T2YoIjoiKTtpZigtMT09PXIpcmV0dXJuIHQuZGVzdHJveSgpLGUobmV3IEVycm9yKGBJbnZhbGlkIGhlYWRlciBmcm9tIHByb3h5IENPTk5FQ1QgcmVzcG9uc2U6ICIke259ImApKTtjb25zdCBvPW4uc2xpY2UoMCxyKS50b0xvd2VyQ2FzZSgpLHM9bi5zbGljZShyKzEpLnRyaW1TdGFydCgpLGk9bVtvXTsic3RyaW5nIj09dHlwZW9mIGk/bVtvXT1baSxzXTpBcnJheS5pc0FycmF5KGkpP2kucHVzaChzKTptW29dPXN9Y24oImdvdCBwcm94eSBzZXJ2ZXIgcmVzcG9uc2U6ICVvICVvIixoLG0pLGkoKSxuKHtjb25uZWN0OntzdGF0dXNDb2RlOmwsc3RhdHVzVGV4dDpkLGhlYWRlcnM6bX0sYnVmZmVyZWQ6dX0pfShjKTp0Lm9uY2UoInJlYWRhYmxlIixzKX1mdW5jdGlvbiBpKCl7dC5yZW1vdmVMaXN0ZW5lcigiZW5kIixjKSx0LnJlbW92ZUxpc3RlbmVyKCJlcnJvciIsdSksdC5yZW1vdmVMaXN0ZW5lcigicmVhZGFibGUiLHMpfWZ1bmN0aW9uIGMoKXtpKCksY24oIm9uZW5kIiksZShuZXcgRXJyb3IoIlByb3h5IGNvbm5lY3Rpb24gZW5kZWQgYmVmb3JlIHJlY2VpdmluZyBDT05ORUNUIHJlc3BvbnNlIikpfWZ1bmN0aW9uIHUodCl7aSgpLGNuKCJvbmVycm9yICVvIix0KSxlKHQpfXQub24oImVycm9yIix1KSx0Lm9uKCJlbmQiLGMpLHMoKX0pKX1mdW5jdGlvbiBhbiguLi50KXtrLmxvZygiW2h0dHBzLXByb3h5LWFnZW50XSIsLi4udCl9Y2xhc3MgZm4gZXh0ZW5kcyBzbntzdGF0aWMgX19pbml0U3RhdGljKCl7dGhpcy5wcm90b2NvbHM9WyJodHRwIiwiaHR0cHMiXX1jb25zdHJ1Y3Rvcih0LG4pe3N1cGVyKG4pLHRoaXMub3B0aW9ucz17fSx0aGlzLnByb3h5PSJzdHJpbmciPT10eXBlb2YgdD9uZXcgVVJMKHQpOnQsdGhpcy5wcm94eUhlYWRlcnM9bj8uaGVhZGVycz8/e30sYW4oIkNyZWF0aW5nIG5ldyBIdHRwc1Byb3h5QWdlbnQgaW5zdGFuY2U6ICVvIix0aGlzLnByb3h5LmhyZWYpO2NvbnN0IGU9KHRoaXMucHJveHkuaG9zdG5hbWV8fHRoaXMucHJveHkuaG9zdCkucmVwbGFjZSgvXlxbfFxdJC9nLCIiKSxyPXRoaXMucHJveHkucG9ydD9wYXJzZUludCh0aGlzLnByb3h5LnBvcnQsMTApOiJodHRwczoiPT09dGhpcy5wcm94eS5wcm90b2NvbD80NDM6ODA7dGhpcy5jb25uZWN0T3B0cz17QUxQTlByb3RvY29sczpbImh0dHAvMS4xIl0sLi4ubj9wbihuLCJoZWFkZXJzIik6bnVsbCxob3N0OmUscG9ydDpyfX1hc3luYyBjb25uZWN0KHQsbil7Y29uc3R7cHJveHk6ZX09dGhpcztpZighbi5ob3N0KXRocm93IG5ldyBUeXBlRXJyb3IoJ05vICJob3N0IiBwcm92aWRlZCcpO2xldCByO2lmKCJodHRwczoiPT09ZS5wcm90b2NvbCl7YW4oIkNyZWF0aW5nIGB0bHMuU29ja2V0YDogJW8iLHRoaXMuY29ubmVjdE9wdHMpO2NvbnN0IHQ9dGhpcy5jb25uZWN0T3B0cy5zZXJ2ZXJuYW1lfHx0aGlzLmNvbm5lY3RPcHRzLmhvc3Q7cj1mLmNvbm5lY3Qoey4uLnRoaXMuY29ubmVjdE9wdHMsc2VydmVybmFtZTp0JiZhLmlzSVAodCk/dm9pZCAwOnR9KX1lbHNlIGFuKCJDcmVhdGluZyBgbmV0LlNvY2tldGA6ICVvIix0aGlzLmNvbm5lY3RPcHRzKSxyPWEuY29ubmVjdCh0aGlzLmNvbm5lY3RPcHRzKTtjb25zdCBvPSJmdW5jdGlvbiI9PXR5cGVvZiB0aGlzLnByb3h5SGVhZGVycz90aGlzLnByb3h5SGVhZGVycygpOnsuLi50aGlzLnByb3h5SGVhZGVyc30scz1hLmlzSVB2NihuLmhvc3QpP2BbJHtuLmhvc3R9XWA6bi5ob3N0O2xldCBpPWBDT05ORUNUICR7c306JHtuLnBvcnR9IEhUVFAvMS4xXHJcbmA7aWYoZS51c2VybmFtZXx8ZS5wYXNzd29yZCl7Y29uc3QgdD1gJHtkZWNvZGVVUklDb21wb25lbnQoZS51c2VybmFtZSl9OiR7ZGVjb2RlVVJJQ29tcG9uZW50KGUucGFzc3dvcmQpfWA7b1siUHJveHktQXV0aG9yaXphdGlvbiJdPWBCYXNpYyAke0J1ZmZlci5mcm9tKHQpLnRvU3RyaW5nKCJiYXNlNjQiKX1gfW8uSG9zdD1gJHtzfToke24ucG9ydH1gLG9bIlByb3h5LUNvbm5lY3Rpb24iXXx8KG9bIlByb3h5LUNvbm5lY3Rpb24iXT10aGlzLmtlZXBBbGl2ZT8iS2VlcC1BbGl2ZSI6ImNsb3NlIik7Zm9yKGNvbnN0IHQgb2YgT2JqZWN0LmtleXMobykpaSs9YCR7dH06ICR7b1t0XX1cclxuYDtjb25zdCBjPXVuKHIpO3Iud3JpdGUoYCR7aX1cclxuYCk7Y29uc3R7Y29ubmVjdDp1LGJ1ZmZlcmVkOmh9PWF3YWl0IGM7aWYodC5lbWl0KCJwcm94eUNvbm5lY3QiLHUpLHRoaXMuZW1pdCgicHJveHlDb25uZWN0Iix1LHQpLDIwMD09PXUuc3RhdHVzQ29kZSl7aWYodC5vbmNlKCJzb2NrZXQiLGhuKSxuLnNlY3VyZUVuZHBvaW50KXthbigiVXBncmFkaW5nIHNvY2tldCBjb25uZWN0aW9uIHRvIFRMUyIpO2NvbnN0IHQ9bi5zZXJ2ZXJuYW1lfHxuLmhvc3Q7cmV0dXJuIGYuY29ubmVjdCh7Li4ucG4obiwiaG9zdCIsInBhdGgiLCJwb3J0Iiksc29ja2V0OnIsc2VydmVybmFtZTphLmlzSVAodCk/dm9pZCAwOnR9KX1yZXR1cm4gcn1yLmRlc3Ryb3koKTtjb25zdCBwPW5ldyBhLlNvY2tldCh7d3JpdGFibGU6ITF9KTtyZXR1cm4gcC5yZWFkYWJsZT0hMCx0Lm9uY2UoInNvY2tldCIsKHQ9PnthbigiUmVwbGF5aW5nIHByb3h5IGJ1ZmZlciBmb3IgZmFpbGVkIHJlcXVlc3QiKSx0LnB1c2goaCksdC5wdXNoKG51bGwpfSkpLHB9fWZ1bmN0aW9uIGhuKHQpe3QucmVzdW1lKCl9ZnVuY3Rpb24gcG4odCwuLi5uKXtjb25zdCBlPXt9O2xldCByO2ZvcihyIGluIHQpbi5pbmNsdWRlcyhyKXx8KGVbcl09dFtyXSk7cmV0dXJuIGV9Zm4uX19pbml0U3RhdGljKCk7Y29uc3QgbG49MzI3Njg7ZnVuY3Rpb24gZG4odCl7cmV0dXJuIHQucmVwbGFjZSgvXltBLVpdOi8sIiIpLnJlcGxhY2UoL1xcL2csIi8iKX1jb25zdCBtbj1uO2xldCBnbix5bj0wLGJuPXt9O2Z1bmN0aW9uIF9uKHQpe21uLmRlYnVnJiZjb25zb2xlLmxvZyhgW0FOUiBXb3JrZXJdICR7dH1gKX12YXIgdm4sd24sU247Y29uc3QgJG49ZnVuY3Rpb24odCl7bGV0IG47dHJ5e249bmV3IFVSTCh0LnVybCl9Y2F0Y2gobil7cmV0dXJuIFIoKCgpPT57Y29uc29sZS53YXJuKCJbQHNlbnRyeS9ub2RlXTogSW52YWxpZCBkc24gb3IgdHVubmVsIG9wdGlvbiwgd2lsbCBub3Qgc2VuZCBhbnkgZXZlbnRzLiBUaGUgdHVubmVsIG9wdGlvbiBtdXN0IGJlIGEgZnVsbCBVUkwgd2hlbiB1c2VkLiIpfSkpLHRuKHQsKCgpPT5Qcm9taXNlLnJlc29sdmUoe30pKSl9Y29uc3QgZT0iaHR0cHM6Ij09PW4ucHJvdG9jb2wscj1mdW5jdGlvbih0LG4pe2NvbnN0e25vX3Byb3h5OmV9PXByb2Nlc3MuZW52LHI9ZT8uc3BsaXQoIiwiKS5zb21lKChuPT50Lmhvc3QuZW5kc1dpdGgobil8fHQuaG9zdG5hbWUuZW5kc1dpdGgobikpKTtyZXR1cm4gcj92b2lkIDA6bn0obix0LnByb3h5fHwoZT9wcm9jZXNzLmVudi5odHRwc19wcm94eTp2b2lkIDApfHxwcm9jZXNzLmVudi5odHRwX3Byb3h5KSxvPWU/aTpzLGE9dm9pZCAwIT09dC5rZWVwQWxpdmUmJnQua2VlcEFsaXZlLGY9cj9uZXcgZm4ocik6bmV3IG8uQWdlbnQoe2tlZXBBbGl2ZTphLG1heFNvY2tldHM6MzAsdGltZW91dDoyZTN9KSxoPWZ1bmN0aW9uKHQsbixlKXtjb25zdHtob3N0bmFtZTpyLHBhdGhuYW1lOm8scG9ydDpzLHByb3RvY29sOmksc2VhcmNoOmF9PW5ldyBVUkwodC51cmwpO3JldHVybiBmdW5jdGlvbihmKXtyZXR1cm4gbmV3IFByb21pc2UoKChoLHApPT57WXQoKCgpPT57bGV0IGw9ZnVuY3Rpb24odCl7cmV0dXJuIG5ldyBjKHtyZWFkKCl7dGhpcy5wdXNoKHQpLHRoaXMucHVzaChudWxsKX19KX0oZi5ib2R5KTtjb25zdCBkPXsuLi50LmhlYWRlcnN9O2YuYm9keS5sZW5ndGg+bG4mJihkWyJjb250ZW50LWVuY29kaW5nIl09Imd6aXAiLGw9bC5waXBlKHUoKSkpO2NvbnN0IG09bi5yZXF1ZXN0KHttZXRob2Q6IlBPU1QiLGFnZW50OmUsaGVhZGVyczpkLGhvc3RuYW1lOnIscGF0aDpgJHtvfSR7YX1gLHBvcnQ6cyxwcm90b2NvbDppLGNhOnQuY2FDZXJ0c30sKHQ9Pnt0Lm9uKCJkYXRhIiwoKCk9Pnt9KSksdC5vbigiZW5kIiwoKCk9Pnt9KSksdC5zZXRFbmNvZGluZygidXRmOCIpO2NvbnN0IG49dC5oZWFkZXJzWyJyZXRyeS1hZnRlciJdPz9udWxsLGU9dC5oZWFkZXJzWyJ4LXNlbnRyeS1yYXRlLWxpbWl0cyJdPz9udWxsO2goe3N0YXR1c0NvZGU6dC5zdGF0dXNDb2RlLGhlYWRlcnM6eyJyZXRyeS1hZnRlciI6biwieC1zZW50cnktcmF0ZS1saW1pdHMiOkFycmF5LmlzQXJyYXkoZSk/ZVswXXx8bnVsbDplfX0pfSkpO20ub24oImVycm9yIixwKSxsLnBpcGUobSl9KSl9KSl9fSh0LHQuaHR0cE1vZHVsZT8/byxmKTtyZXR1cm4gdG4odCxoKX0oe3VybDoodm49bW4uZHNuLHduPW1uLnR1bm5lbCxTbj1tbi5zZGtNZXRhZGF0YS5zZGssd258fGAke2Z1bmN0aW9uKHQpe3JldHVybmAke2Z1bmN0aW9uKHQpe2NvbnN0IG49dC5wcm90b2NvbD9gJHt0LnByb3RvY29sfTpgOiIiLGU9dC5wb3J0P2A6JHt0LnBvcnR9YDoiIjtyZXR1cm5gJHtufS8vJHt0Lmhvc3R9JHtlfSR7dC5wYXRoP2AvJHt0LnBhdGh9YDoiIn0vYXBpL2B9KHQpfSR7dC5wcm9qZWN0SWR9L2VudmVsb3BlL2B9KHZuKX0/JHtmdW5jdGlvbih0LG4pe2NvbnN0IGU9e3NlbnRyeV92ZXJzaW9uOkt0fTtyZXR1cm4gdC5wdWJsaWNLZXkmJihlLnNlbnRyeV9rZXk9dC5wdWJsaWNLZXkpLG4mJihlLnNlbnRyeV9jbGllbnQ9YCR7bi5uYW1lfS8ke24udmVyc2lvbn1gKSxuZXcgVVJMU2VhcmNoUGFyYW1zKGUpLnRvU3RyaW5nKCl9KHZuLFNuKX1gKX0pO2FzeW5jIGZ1bmN0aW9uIEVuKCl7aWYoZ24pe19uKCJTZW5kaW5nIGFibm9ybWFsIHNlc3Npb24iKSxCKGduLHtzdGF0dXM6ImFibm9ybWFsIixhYm5vcm1hbF9tZWNoYW5pc206ImFucl9mb3JlZ3JvdW5kIixyZWxlYXNlOm1uLnJlbGVhc2UsZW52aXJvbm1lbnQ6bW4uZW52aXJvbm1lbnR9KTtjb25zdCB0PWZ1bmN0aW9uKHQsbixlLHIpe2NvbnN0IG89QnQoZSk7cmV0dXJuIEF0KHtzZW50X2F0OihuZXcgRGF0ZSkudG9JU09TdHJpbmcoKSwuLi5vJiZ7c2RrOm99LC4uLiEhciYmbiYme2RzbjpqdChuKX19LFsiYWdncmVnYXRlcyJpbiB0P1t7dHlwZToic2Vzc2lvbnMifSx0XTpbe3R5cGU6InNlc3Npb24ifSx0LnRvSlNPTigpXV0pfShnbixtbi5kc24sbW4uc2RrTWV0YWRhdGEsbW4udHVubmVsKTtfbihKU09OLnN0cmluZ2lmeSh0KSksYXdhaXQgJG4uc2VuZCh0KTt0cnl7ZT8ucG9zdE1lc3NhZ2UoInNlc3Npb24tZW5kZWQiKX1jYXRjaCh0KXt9fX1mdW5jdGlvbiB4bih0KXtpZighdClyZXR1cm47Y29uc3Qgbj1mdW5jdGlvbih0KXtpZighdC5sZW5ndGgpcmV0dXJuW107Y29uc3Qgbj1BcnJheS5mcm9tKHQpO3JldHVybi9zZW50cnlXcmFwcGVkLy50ZXN0KE50KG4pLmZ1bmN0aW9ufHwiIikmJm4ucG9wKCksbi5yZXZlcnNlKCkseHQudGVzdChOdChuKS5mdW5jdGlvbnx8IiIpJiYobi5wb3AoKSx4dC50ZXN0KE50KG4pLmZ1bmN0aW9ufHwiIikmJm4ucG9wKCkpLG4uc2xpY2UoMCwkdCkubWFwKCh0PT4oey4uLnQsZmlsZW5hbWU6dC5maWxlbmFtZXx8TnQobikuZmlsZW5hbWUsZnVuY3Rpb246dC5mdW5jdGlvbnx8RXR9KSkpfSh0KTtpZihtbi5hcHBSb290UGF0aClmb3IoY29uc3QgdCBvZiBuKXQuZmlsZW5hbWUmJih0LmZpbGVuYW1lPU90KHQuZmlsZW5hbWUsbW4uYXBwUm9vdFBhdGgpKTtyZXR1cm4gbn1hc3luYyBmdW5jdGlvbiBObih0LG4pe2lmKHluPj1tbi5tYXhBbnJFdmVudHMpcmV0dXJuO3luKz0xLGF3YWl0IEVuKCksX24oIlNlbmRpbmcgZXZlbnQiKTtjb25zdCBlPXtldmVudF9pZDpBKCksY29udGV4dHM6bW4uY29udGV4dHMscmVsZWFzZTptbi5yZWxlYXNlLGVudmlyb25tZW50Om1uLmVudmlyb25tZW50LGRpc3Q6bW4uZGlzdCxwbGF0Zm9ybToibm9kZSIsbGV2ZWw6ImVycm9yIixleGNlcHRpb246e3ZhbHVlczpbe3R5cGU6IkFwcGxpY2F0aW9uTm90UmVzcG9uZGluZyIsdmFsdWU6YEFwcGxpY2F0aW9uIE5vdCBSZXNwb25kaW5nIGZvciBhdCBsZWFzdCAke21uLmFuclRocmVzaG9sZH0gbXNgLHN0YWNrdHJhY2U6e2ZyYW1lczp4bih0KX0sbWVjaGFuaXNtOnt0eXBlOiJBTlIifX1dfSx0YWdzOm1uLnN0YXRpY1RhZ3N9O24mJmZ1bmN0aW9uKHQsbil7aWYoV3QodCxuKSwhdC5jb250ZXh0cz8udHJhY2Upe2NvbnN0e3RyYWNlSWQ6ZSxwYXJlbnRTcGFuSWQ6cixwcm9wYWdhdGlvblNwYW5JZDpvfT1uLnByb3BhZ2F0aW9uQ29udGV4dDt0LmNvbnRleHRzPXt0cmFjZTp7dHJhY2VfaWQ6ZSxzcGFuX2lkOm98fEYoKSxwYXJlbnRfc3Bhbl9pZDpyfSwuLi50LmNvbnRleHRzfX19KGUsbiksZnVuY3Rpb24odCl7aWYoMD09PU9iamVjdC5rZXlzKGJuKS5sZW5ndGgpcmV0dXJuO2NvbnN0IG49bW4uYXBwUm9vdFBhdGg/e306Ym47aWYobW4uYXBwUm9vdFBhdGgpZm9yKGNvbnN0W3QsZV1vZiBPYmplY3QuZW50cmllcyhibikpbltPdCh0LG1uLmFwcFJvb3RQYXRoKV09ZTtjb25zdCBlPW5ldyBNYXA7Zm9yKGNvbnN0IHIgb2YgdC5leGNlcHRpb24/LnZhbHVlc3x8W10pZm9yKGNvbnN0IHQgb2Ygci5zdGFja3RyYWNlPy5mcmFtZXN8fFtdKXtjb25zdCByPXQuYWJzX3BhdGh8fHQuZmlsZW5hbWU7ciYmbltyXSYmZS5zZXQocixuW3JdKX1pZihlLnNpemU+MCl7Y29uc3Qgbj1bXTtmb3IoY29uc3RbdCxyXW9mIGUuZW50cmllcygpKW4ucHVzaCh7dHlwZToic291cmNlbWFwIixjb2RlX2ZpbGU6dCxkZWJ1Z19pZDpyfSk7dC5kZWJ1Z19tZXRhPXtpbWFnZXM6bn19fShlKTtjb25zdCByPUd0KGUsbW4uZHNuLG1uLnNka01ldGFkYXRhLG1uLnR1bm5lbCk7X24oSlNPTi5zdHJpbmdpZnkocikpLGF3YWl0ICRuLnNlbmQociksYXdhaXQgJG4uZmx1c2goMmUzKSx5bj49bW4ubWF4QW5yRXZlbnRzJiZzZXRUaW1lb3V0KCgoKT0+e3Byb2Nlc3MuZXhpdCgwKX0pLDVlMyl9bGV0IFRuO2lmKF9uKCJTdGFydGVkIiksbW4uY2FwdHVyZVN0YWNrVHJhY2Upe19uKCJDb25uZWN0aW5nIHRvIGRlYnVnZ2VyIik7Y29uc3Qgbj1uZXcgdDtuLmNvbm5lY3RUb01haW5UaHJlYWQoKSxfbigiQ29ubmVjdGVkIHRvIGRlYnVnZ2VyIik7Y29uc3QgZT1uZXcgTWFwO24ub24oIkRlYnVnZ2VyLnNjcmlwdFBhcnNlZCIsKHQ9PntlLnNldCh0LnBhcmFtcy5zY3JpcHRJZCx0LnBhcmFtcy51cmwpfSkpLG4ub24oIkRlYnVnZ2VyLnBhdXNlZCIsKHQ9PntpZigib3RoZXIiPT09dC5wYXJhbXMucmVhc29uKXRyeXtfbigiRGVidWdnZXIgcGF1c2VkIik7Y29uc3Qgcz1bLi4udC5wYXJhbXMuY2FsbEZyYW1lc10saT1tbi5hcHBSb290UGF0aD9mdW5jdGlvbih0PShwcm9jZXNzLmFyZ3ZbMV0/ZW4ocHJvY2Vzcy5hcmd2WzFdKTpwcm9jZXNzLmN3ZCgpKSxuPSJcXCI9PT1vKXtjb25zdCBlPW4/ZG4odCk6dDtyZXR1cm4gdD0+e2lmKCF0KXJldHVybjtjb25zdCBvPW4/ZG4odCk6dDtsZXR7ZGlyOnMsYmFzZTppLGV4dDpjfT1yLnBhcnNlKG8pOyIuanMiIT09YyYmIi5tanMiIT09YyYmIi5janMiIT09Y3x8KGk9aS5zbGljZSgwLC0xKmMubGVuZ3RoKSk7Y29uc3QgdT1kZWNvZGVVUklDb21wb25lbnQoaSk7c3x8KHM9Ii4iKTtjb25zdCBhPXMubGFzdEluZGV4T2YoIi9ub2RlX21vZHVsZXMiKTtpZihhPi0xKXJldHVybmAke3Muc2xpY2UoYSsxNCkucmVwbGFjZSgvXC8vZywiLiIpfToke3V9YDtpZihzLnN0YXJ0c1dpdGgoZSkpe2NvbnN0IHQ9cy5zbGljZShlLmxlbmd0aCsxKS5yZXBsYWNlKC9cLy9nLCIuIik7cmV0dXJuIHQ/YCR7dH06JHt1fWA6dX1yZXR1cm4gdX19KG1uLmFwcFJvb3RQYXRoKTooKT0+e30sYz1zLm1hcCgodD0+ZnVuY3Rpb24odCxuLGUpe2NvbnN0IHI9bj9uLnJlcGxhY2UoL15maWxlOlwvXC8vLCIiKTp2b2lkIDAsbz10LmxvY2F0aW9uLmNvbHVtbk51bWJlcj90LmxvY2F0aW9uLmNvbHVtbk51bWJlcisxOnZvaWQgMCxzPXQubG9jYXRpb24ubGluZU51bWJlcj90LmxvY2F0aW9uLmxpbmVOdW1iZXIrMTp2b2lkIDA7cmV0dXJue2ZpbGVuYW1lOnIsbW9kdWxlOmUociksZnVuY3Rpb246dC5mdW5jdGlvbk5hbWV8fEV0LGNvbG5vOm8sbGluZW5vOnMsaW5fYXBwOnI/cm4ocik6dm9pZCAwfX0odCxlLmdldCh0LmxvY2F0aW9uLnNjcmlwdElkKSxpKSkpLHU9c2V0VGltZW91dCgoKCk9PntObihjKS50aGVuKG51bGwsKCgpPT57X24oIlNlbmRpbmcgQU5SIGV2ZW50IGZhaWxlZC4iKX0pKX0pLDVlMyk7bi5wb3N0KCJSdW50aW1lLmV2YWx1YXRlIix7ZXhwcmVzc2lvbjoiZ2xvYmFsLl9fU0VOVFJZX0dFVF9TQ09QRVNfXygpOyIsc2lsZW50OiEwLHJldHVybkJ5VmFsdWU6ITB9LCgodCxlKT0+e3QmJl9uKGBFcnJvciBleGVjdXRpbmcgc2NyaXB0OiAnJHt0Lm1lc3NhZ2V9J2ApLGNsZWFyVGltZW91dCh1KTtjb25zdCByPWU/LnJlc3VsdD9lLnJlc3VsdC52YWx1ZTp2b2lkIDA7bi5wb3N0KCJEZWJ1Z2dlci5yZXN1bWUiKSxuLnBvc3QoIkRlYnVnZ2VyLmRpc2FibGUiKSxObihjLHIpLnRoZW4obnVsbCwoKCk9PntfbigiU2VuZGluZyBBTlIgZXZlbnQgZmFpbGVkLiIpfSkpfSkpfWNhdGNoKHQpe3Rocm93IG4ucG9zdCgiRGVidWdnZXIucmVzdW1lIiksbi5wb3N0KCJEZWJ1Z2dlci5kaXNhYmxlIiksdH19KSksVG49KCk9Pnt0cnl7bi5wb3N0KCJEZWJ1Z2dlci5lbmFibGUiLCgoKT0+e24ucG9zdCgiRGVidWdnZXIucGF1c2UiKX0pKX1jYXRjaCh0KXt9fX1jb25zdHtwb2xsOkNufT1mdW5jdGlvbih0LG4sZSxyKXtjb25zdCBvPXQoKTtsZXQgcz0hMSxpPSEwO3JldHVybiBzZXRJbnRlcnZhbCgoKCk9Pntjb25zdCB0PW8uZ2V0VGltZU1zKCk7ITE9PT1zJiZ0Pm4rZSYmKHM9ITAsaSYmcigpKSx0PG4rZSYmKHM9ITEpfSksMjApLHtwb2xsOigpPT57by5yZXNldCgpfSxlbmFibGVkOnQ9PntpPXR9fX0oKGZ1bmN0aW9uKCl7bGV0IHQ9cHJvY2Vzcy5ocnRpbWUoKTtyZXR1cm57Z2V0VGltZU1zOigpPT57Y29uc3RbbixlXT1wcm9jZXNzLmhydGltZSh0KTtyZXR1cm4gTWF0aC5mbG9vcigxZTMqbitlLzFlNil9LHJlc2V0OigpPT57dD1wcm9jZXNzLmhydGltZSgpfX19KSxtbi5wb2xsSW50ZXJ2YWwsbW4uYW5yVGhyZXNob2xkLChmdW5jdGlvbigpe19uKCJXYXRjaGRvZyB0aW1lb3V0IiksVG4/KF9uKCJQYXVzaW5nIGRlYnVnZ2VyIHRvIGNhcHR1cmUgc3RhY2sgdHJhY2UiKSxUbigpKTooX24oIkNhcHR1cmluZyBldmVudCB3aXRob3V0IGEgc3RhY2sgdHJhY2UiKSxObigpLnRoZW4obnVsbCwoKCk9PntfbigiU2VuZGluZyBBTlIgZXZlbnQgZmFpbGVkIG9uIHdhdGNoZG9nIHRpbWVvdXQuIil9KSkpfSkpO2U/Lm9uKCJtZXNzYWdlIiwodD0+e3Quc2Vzc2lvbiYmKGduPUwodC5zZXNzaW9uKSksdC5kZWJ1Z0ltYWdlcyYmKGJuPXQuZGVidWdJbWFnZXMpLENuKCl9KSk7';
|
|
11
11
|
|
|
12
12
|
const DEFAULT_INTERVAL = 50;
|
|
13
13
|
const DEFAULT_HANG_THRESHOLD = 5000;
|