Files
e-tib.com/.next/dev/server/vendor-chunks/@fastify+otel@0.18.0_@opentelemetry+api@1.9.1.js
Marc Mintel d14122005d Initial commit: E-TIB production hardening & E2E foundation
Former-commit-id: ef04fca3d76375630c05aac117bf586953f3b657
2026-04-28 19:11:38 +02:00

55 lines
109 KiB
JavaScript

"use strict";
/*
* ATTENTION: An "eval-source-map" devtool has been used.
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
exports.id = "vendor-chunks/@fastify+otel@0.18.0_@opentelemetry+api@1.9.1";
exports.ids = ["vendor-chunks/@fastify+otel@0.18.0_@opentelemetry+api@1.9.1"];
exports.modules = {
/***/ "(rsc)/./node_modules/.pnpm/@fastify+otel@0.18.0_@opentelemetry+api@1.9.1/node_modules/@fastify/otel/index.js":
/*!**************************************************************************************************************!*\
!*** ./node_modules/.pnpm/@fastify+otel@0.18.0_@opentelemetry+api@1.9.1/node_modules/@fastify/otel/index.js ***!
\**************************************************************************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
eval("\nconst dc = __webpack_require__(/*! node:diagnostics_channel */ \"node:diagnostics_channel\")\nconst { context, trace, SpanStatusCode, propagation, diag } = __webpack_require__(/*! @opentelemetry/api */ \"(rsc)/./node_modules/.pnpm/@opentelemetry+api@1.9.1/node_modules/@opentelemetry/api/build/esm/index.js\")\nconst { getRPCMetadata, RPCType } = __webpack_require__(/*! @opentelemetry/core */ \"(rsc)/./node_modules/.pnpm/@opentelemetry+core@2.6.1_@opentelemetry+api@1.9.1/node_modules/@opentelemetry/core/build/esm/index.js\")\nconst {\n ATTR_HTTP_ROUTE,\n ATTR_HTTP_RESPONSE_STATUS_CODE,\n ATTR_HTTP_REQUEST_METHOD,\n ATTR_URL_PATH\n} = __webpack_require__(/*! @opentelemetry/semantic-conventions */ \"(rsc)/./node_modules/.pnpm/@opentelemetry+semantic-conventions@1.40.0/node_modules/@opentelemetry/semantic-conventions/build/esm/index.js\")\nconst { InstrumentationBase } = __webpack_require__(/*! @opentelemetry/instrumentation */ \"(rsc)/./node_modules/.pnpm/@opentelemetry+instrumentation@0.212.0_@opentelemetry+api@1.9.1/node_modules/@opentelemetry/instrumentation/build/esm/index.js\")\n\nconst {\n version: PACKAGE_VERSION,\n name: PACKAGE_NAME\n} = __webpack_require__(/*! ./package.json */ \"(rsc)/./node_modules/.pnpm/@fastify+otel@0.18.0_@opentelemetry+api@1.9.1/node_modules/@fastify/otel/package.json\")\n\n// Constants\nconst SUPPORTED_VERSIONS = '>=4.0.0 <6'\nconst FASTIFY_HOOKS = [\n 'onRequest',\n 'preParsing',\n 'preValidation',\n 'preHandler',\n 'preSerialization',\n 'onSend',\n 'onResponse',\n 'onError'\n]\nconst ATTRIBUTE_NAMES = {\n HOOK_NAME: 'hook.name',\n FASTIFY_TYPE: 'fastify.type',\n HOOK_CALLBACK_NAME: 'hook.callback.name',\n ROOT: 'fastify.root'\n}\nconst HOOK_TYPES = {\n ROUTE: 'route-hook',\n INSTANCE: 'hook',\n HANDLER: 'request-handler'\n}\nconst ANONYMOUS_FUNCTION_NAME = 'anonymous'\n\n// Symbols\nconst kInstrumentation = Symbol('fastify otel instance')\nconst kRequestSpan = Symbol('fastify otel request spans')\nconst kRequestContext = Symbol('fastify otel request context')\nconst kAddHookOriginal = Symbol('fastify otel addhook original')\nconst kSetNotFoundOriginal = Symbol('fastify otel setnotfound original')\nconst kIgnorePaths = Symbol('fastify otel ignore path')\nconst kRecordExceptions = Symbol('fastify otel record exceptions')\n\nclass FastifyOtelInstrumentation extends InstrumentationBase {\n logger = null\n _requestHook = null\n _lifecycleHook = null\n\n constructor (config) {\n super(PACKAGE_NAME, PACKAGE_VERSION, config)\n this.logger = diag.createComponentLogger({ namespace: PACKAGE_NAME })\n this[kIgnorePaths] = null\n this[kRecordExceptions] = true\n\n if (config?.recordExceptions != null) {\n if (typeof config.recordExceptions !== 'boolean') {\n throw new TypeError('recordExceptions must be a boolean')\n }\n\n this[kRecordExceptions] = config.recordExceptions\n }\n if (typeof config?.requestHook === 'function') {\n this._requestHook = config.requestHook\n }\n if (typeof config?.lifecycleHook === 'function') {\n this._lifecycleHook = config.lifecycleHook\n }\n\n if (config?.ignorePaths != null || process.env.OTEL_FASTIFY_IGNORE_PATHS != null) {\n const ignorePaths = config?.ignorePaths ?? process.env.OTEL_FASTIFY_IGNORE_PATHS\n\n if ((typeof ignorePaths !== 'string' || ignorePaths.length === 0) && typeof ignorePaths !== 'function') {\n throw new TypeError(\n 'ignorePaths must be a string or a function'\n )\n }\n\n let globMatcher = null\n\n this[kIgnorePaths] = (routeOptions) => {\n if (typeof ignorePaths === 'function') {\n return ignorePaths(routeOptions)\n } else {\n // Using minimatch to match the path until path.matchesGlob is out of experimental\n // path.matchesGlob uses minimatch internally\n if (globMatcher == null) {\n globMatcher = (__webpack_require__(/*! minimatch */ \"(rsc)/./node_modules/.pnpm/minimatch@10.2.5/node_modules/minimatch/dist/commonjs/index.js\").minimatch)\n }\n\n return globMatcher(routeOptions.url, ignorePaths)\n }\n }\n }\n }\n\n enable () {\n if (this._handleInitialization === undefined && this.getConfig().registerOnInitialization) {\n this._handleInitialization = (message) => {\n // Cannot use `fastify.register(plugin)` because it is lazily executed and\n // thus requires user code to await fastify instance first.\n this.plugin()(message.fastify, undefined, () => {})\n\n // Add an empty plugin to keep `app.hasPlugin('@fastify/otel')` invariant\n const emptyPlugin = (_, __, done) => {\n done()\n }\n emptyPlugin[Symbol.for('skip-override')] = true\n emptyPlugin[Symbol.for('fastify.display-name')] = '@fastify/otel'\n message.fastify.register(emptyPlugin)\n }\n dc.subscribe('fastify.initialization', this._handleInitialization)\n }\n return super.enable()\n }\n\n disable () {\n if (this._handleInitialization) {\n dc.unsubscribe('fastify.initialization', this._handleInitialization)\n this._handleInitialization = undefined\n }\n return super.disable()\n }\n\n // We do not do patching in this instrumentation\n init () {\n return []\n }\n\n plugin () {\n const instrumentation = this\n\n FastifyInstrumentationPlugin[Symbol.for('skip-override')] = true\n FastifyInstrumentationPlugin[Symbol.for('fastify.display-name')] = '@fastify/otel'\n FastifyInstrumentationPlugin[Symbol.for('plugin-meta')] = {\n fastify: SUPPORTED_VERSIONS,\n name: '@fastify/otel',\n }\n\n return FastifyInstrumentationPlugin\n\n function FastifyInstrumentationPlugin (instance, opts, done) {\n instance.decorate(kInstrumentation, instrumentation)\n // addHook and notfoundHandler are essentially inherited from the prototype\n // what is important is to bound it to the right instance\n instance.decorate(kAddHookOriginal, instance.addHook)\n instance.decorate(kSetNotFoundOriginal, instance.setNotFoundHandler)\n instance.decorateRequest('opentelemetry', function openetelemetry () {\n const ctx = this[kRequestContext]\n const span = this[kRequestSpan]\n\n return {\n enabled: this.routeOptions.config?.otel !== false,\n span,\n tracer: instrumentation.tracer,\n context: ctx,\n inject: (carrier, setter) => {\n return propagation.inject(ctx, carrier, setter)\n },\n extract: (carrier, getter) => {\n return propagation.extract(ctx, carrier, getter)\n }\n }\n })\n instance.decorateRequest(kRequestSpan, null)\n instance.decorateRequest(kRequestContext, null)\n\n instance.addHook('onRoute', function otelWireRoute (routeOptions) {\n if (instrumentation[kIgnorePaths]?.(routeOptions) === true) {\n instrumentation.logger.debug(\n `Ignoring route instrumentation ${routeOptions.method} ${routeOptions.url} because it matches the ignore path`\n )\n return\n }\n\n if (routeOptions.config?.otel === false) {\n instrumentation.logger.debug(\n `Ignoring route instrumentation ${routeOptions.method} ${routeOptions.url} because it is disabled`\n )\n\n return\n }\n\n for (const hook of FASTIFY_HOOKS) {\n if (routeOptions[hook] != null) {\n const handlerLike = routeOptions[hook]\n\n if (typeof handlerLike === 'function') {\n routeOptions[hook] = handlerWrapper(handlerLike, hook, {\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - route -> ${hook}`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.ROUTE,\n [ATTR_HTTP_ROUTE]: routeOptions.url,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n handlerLike.name?.length > 0\n ? handlerLike.name\n : ANONYMOUS_FUNCTION_NAME /* c8 ignore next */\n })\n } else if (Array.isArray(handlerLike)) {\n const wrappedHandlers = []\n\n for (const handler of handlerLike) {\n wrappedHandlers.push(\n handlerWrapper(handler, hook, {\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - route -> ${hook}`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.ROUTE,\n [ATTR_HTTP_ROUTE]: routeOptions.url,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n handler.name?.length > 0\n ? handler.name\n : ANONYMOUS_FUNCTION_NAME\n })\n )\n }\n\n routeOptions[hook] = wrappedHandlers\n }\n }\n }\n\n // We always want to add the onSend hook to the route to be executed last\n if (routeOptions.onSend != null) {\n routeOptions.onSend = Array.isArray(routeOptions.onSend)\n ? [...routeOptions.onSend, finalizeResponseSpanHook]\n : [routeOptions.onSend, finalizeResponseSpanHook]\n } else {\n routeOptions.onSend = finalizeResponseSpanHook\n }\n\n // We always want to add the onError hook to the route to be executed last\n if (routeOptions.onError != null) {\n routeOptions.onError = Array.isArray(routeOptions.onError)\n ? [...routeOptions.onError, recordErrorInSpanHook]\n : [routeOptions.onError, recordErrorInSpanHook]\n } else {\n routeOptions.onError = recordErrorInSpanHook\n }\n\n routeOptions.handler = handlerWrapper(routeOptions.handler, 'handler', {\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - route-handler`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.HANDLER,\n [ATTR_HTTP_ROUTE]: routeOptions.url,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n routeOptions.handler.name.length > 0\n ? routeOptions.handler.name\n : ANONYMOUS_FUNCTION_NAME\n })\n })\n\n instance.addHook('onRequest', function startRequestSpanHook (request, _reply, hookDone) {\n if (\n this[kInstrumentation].isEnabled() === false ||\n request.routeOptions.config?.otel === false\n ) {\n return hookDone()\n }\n\n if (this[kInstrumentation][kIgnorePaths]?.({\n url: request.url,\n method: request.method,\n }) === true) {\n this[kInstrumentation].logger.debug(\n `Ignoring request ${request.method} ${request.url} because it matches the ignore path`\n )\n return hookDone()\n }\n\n let ctx = context.active()\n\n if (trace.getSpan(ctx) == null) {\n ctx = propagation.extract(ctx, request.headers)\n }\n\n const rpcMetadata = getRPCMetadata(ctx)\n\n if (\n request.routeOptions.url != null &&\n rpcMetadata?.type === RPCType.HTTP\n ) {\n rpcMetadata.route = request.routeOptions.url\n }\n\n const attributes = {\n [ATTRIBUTE_NAMES.ROOT]: '@fastify/otel',\n [ATTR_HTTP_REQUEST_METHOD]: request.method,\n [ATTR_URL_PATH]: request.url\n }\n\n if (request.routeOptions.url != null) {\n attributes[ATTR_HTTP_ROUTE] = request.routeOptions.url\n }\n\n /** @type {import('@opentelemetry/api').Span} */\n const span = this[kInstrumentation].tracer.startSpan('request', {\n attributes\n }, ctx)\n\n try {\n this[kInstrumentation]._requestHook?.(span, request)\n } catch (err) {\n this[kInstrumentation].logger.error({ err }, 'requestHook threw')\n }\n\n request[kRequestContext] = trace.setSpan(ctx, span)\n request[kRequestSpan] = span\n\n context.with(request[kRequestContext], () => {\n hookDone()\n })\n })\n\n // onResponse is the last hook to be executed, only added for 404 handlers\n instance.addHook('onResponse', function finalizeNotFoundSpanHook (request, reply, hookDone) {\n const span = request[kRequestSpan]\n\n if (span != null) {\n span.setAttributes({\n [ATTR_HTTP_RESPONSE_STATUS_CODE]: reply.statusCode\n })\n span.end()\n }\n\n request[kRequestSpan] = null\n\n hookDone()\n })\n\n instance.addHook = addHookPatched\n instance.setNotFoundHandler = setNotFoundHandlerPatched\n\n done()\n\n function finalizeResponseSpanHook (request, reply, payload, hookDone) {\n /** @type {import('@opentelemetry/api').Span} */\n const span = request[kRequestSpan]\n\n if (span != null) {\n if (reply.statusCode >= 500) {\n span.setStatus({ code: SpanStatusCode.ERROR })\n }\n\n span.setAttributes({\n [ATTR_HTTP_RESPONSE_STATUS_CODE]: reply.statusCode\n })\n span.end()\n }\n\n request[kRequestSpan] = null\n\n hookDone(null, payload)\n }\n\n function recordErrorInSpanHook (request, reply, error, hookDone) {\n /** @type {Span} */\n const span = request[kRequestSpan]\n\n if (span != null) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error.message\n })\n if (instrumentation[kRecordExceptions] !== false) {\n span.recordException(error)\n }\n }\n\n hookDone()\n }\n\n function addHookPatched (name, hook) {\n const addHookOriginal = this[kAddHookOriginal]\n\n if (FASTIFY_HOOKS.includes(name)) {\n return addHookOriginal.call(\n this,\n name,\n handlerWrapper(hook, name, {\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - ${name}`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.INSTANCE,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n hook.name?.length > 0\n ? hook.name\n : ANONYMOUS_FUNCTION_NAME /* c8 ignore next */\n })\n )\n } else {\n return addHookOriginal.call(this, name, hook)\n }\n }\n\n function setNotFoundHandlerPatched (hooks, handler) {\n const setNotFoundHandlerOriginal = this[kSetNotFoundOriginal]\n if (typeof hooks === 'function') {\n handler = handlerWrapper(hooks, 'notFoundHandler', {\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - not-found-handler`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.INSTANCE,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n hooks.name?.length > 0\n ? hooks.name\n : ANONYMOUS_FUNCTION_NAME /* c8 ignore next */\n })\n setNotFoundHandlerOriginal.call(this, handler)\n } else {\n if (hooks.preValidation != null) {\n hooks.preValidation = handlerWrapper(hooks.preValidation, 'notFoundHandler - preValidation', {\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - not-found-handler - preValidation`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.INSTANCE,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n hooks.preValidation.name?.length > 0\n ? hooks.preValidation.name\n : ANONYMOUS_FUNCTION_NAME /* c8 ignore next */\n })\n }\n\n if (hooks.preHandler != null) {\n hooks.preHandler = handlerWrapper(hooks.preHandler, 'notFoundHandler - preHandler', {\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - not-found-handler - preHandler`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.INSTANCE,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n hooks.preHandler.name?.length > 0\n ? hooks.preHandler.name\n : ANONYMOUS_FUNCTION_NAME /* c8 ignore next */\n })\n }\n\n handler = handlerWrapper(handler, 'notFoundHandler', {\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - not-found-handler`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.INSTANCE,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n handler.name?.length > 0\n ? handler.name\n : ANONYMOUS_FUNCTION_NAME /* c8 ignore next */\n })\n setNotFoundHandlerOriginal.call(this, hooks, handler)\n }\n }\n\n // regular handlers are (request, reply), @fastify/websocket handlers are (socket, request)\n function getRequestFromArgs (args) {\n for (const arg of args) {\n if (arg?.routeOptions && arg.url && arg.method) {\n return arg\n }\n }\n return null\n }\n\n function handlerWrapper (handler, hookName, spanAttributes = {}) {\n return function handlerWrapped (...args) {\n /** @type {FastifyOtelInstrumentation} */\n const instrumentation = this[kInstrumentation]\n\n const request = getRequestFromArgs(args)\n if (request === null) {\n instrumentation.logger.debug(\n `Ignoring route instrumentation because ${hookName} was called without a Fastify request argument`\n )\n return handler.call(this, ...args)\n }\n\n if (instrumentation.isEnabled() === false || request.routeOptions.config?.otel === false) {\n instrumentation.logger.debug(\n `Ignoring route instrumentation ${request.routeOptions.method} ${request.routeOptions.url} because it is disabled`\n )\n return handler.call(this, ...args)\n }\n\n if (instrumentation[kIgnorePaths]?.({\n url: request.url,\n method: request.method,\n }) === true) {\n instrumentation.logger.debug(\n `Ignoring route instrumentation ${request.routeOptions.method} ${request.routeOptions.url} because it matches the ignore path`\n )\n return handler.call(this, ...args)\n }\n\n /* c8 ignore next */\n const ctx = request[kRequestContext] ?? context.active()\n const handlerName = handler.name?.length > 0\n ? handler.name\n : this.pluginName /* c8 ignore next */ ?? ANONYMOUS_FUNCTION_NAME /* c8 ignore next */\n\n const span = instrumentation.tracer.startSpan(\n `${hookName} - ${handlerName}`,\n {\n attributes: spanAttributes\n },\n ctx\n )\n\n if (instrumentation._lifecycleHook != null) {\n try {\n instrumentation._lifecycleHook(span, {\n hookName,\n request,\n handler: handlerName\n })\n } catch (err) {\n instrumentation.logger.error({ err }, 'Execution of lifecycleHook failed')\n }\n }\n\n return context.with(\n trace.setSpan(ctx, span),\n function () {\n try {\n const res = handler.call(this, ...args)\n\n if (typeof res?.then === 'function') {\n return res.then(\n result => {\n span.end()\n return result\n },\n error => {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error.message\n })\n if (instrumentation[kRecordExceptions] !== false) {\n span.recordException(error)\n }\n span.end()\n return Promise.reject(error)\n }\n )\n }\n\n span.end()\n return res\n } catch (error) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error.message\n })\n if (instrumentation[kRecordExceptions] !== false) {\n span.recordException(error)\n }\n span.end()\n throw error\n }\n },\n this\n )\n }\n }\n }\n }\n}\n\nmodule.exports = FastifyOtelInstrumentation\nmodule.exports.FastifyOtelInstrumentation = FastifyOtelInstrumentation\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHJzYykvLi9ub2RlX21vZHVsZXMvLnBucG0vQGZhc3RpZnkrb3RlbEAwLjE4LjBfQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4xL25vZGVfbW9kdWxlcy9AZmFzdGlmeS9vdGVsL2luZGV4LmpzIiwibWFwcGluZ3MiOiJBQUFZO0FBQ1osV0FBVyxtQkFBTyxDQUFDLDBEQUEwQjtBQUM3QyxRQUFRLG9EQUFvRCxFQUFFLG1CQUFPLENBQUMsa0lBQW9CO0FBQzFGLFFBQVEsMEJBQTBCLEVBQUUsbUJBQU8sQ0FBQyw4SkFBcUI7QUFDakU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUUsRUFBRSxtQkFBTyxDQUFDLHNMQUFxQztBQUNqRCxRQUFRLHNCQUFzQixFQUFFLG1CQUFPLENBQUMsaU1BQWdDOztBQUV4RTtBQUNBO0FBQ0E7QUFDQSxFQUFFLEVBQUUsbUJBQU8sQ0FBQyx3SUFBZ0I7O0FBRTVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSwrQ0FBK0MseUJBQXlCO0FBQ3hFO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQiw2SUFBOEI7QUFDeEQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMERBQTBEOztBQUUxRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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LDRDQUE0QyxpQkFBaUI7QUFDN0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHFFQUFxRTtBQUNyRTtBQUNBLHFCQUFxQiw0QkFBNEI7QUFDakQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esd0RBQXdELFVBQVU7QUFDbEU7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxnREFBZ0QsNkJBQTZCLEVBQUUsMEJBQTBCO0FBQ3pHO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7QUFDQSxnREFBZ0QsNkJBQTZCLEVBQUUsMEJBQTBCO0FBQ3pHO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZUFBZSxVQUFVLElBQUksWUFBWTtBQUN6QztBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmLGNBQWM7QUFDZCw2Q0FBNkMsS0FBSztBQUNsRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QjtBQUN2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHlDQUF5QyIsInNvdXJjZXMiOlsiL1VzZXJzL21hcmNtaW50ZWwvUHJvamVjdHMvZS10aWIuY29tL25vZGVfbW9kdWxlcy8ucG5wbS9AZmFzdGlmeStvdGVsQDAuMTguMF9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjEvbm9kZV9tb2R1bGVzL0BmYXN0aWZ5L290ZWwvaW5kZXguanMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnXG5jb25zdCBkYyA9IHJlcXVpcmUoJ25vZGU6ZGlhZ25vc3RpY3NfY2hhbm5lbCcpXG5jb25zdCB7IGNvbnRleHQsIHRyYWNlLCBTcGFuU3RhdHVzQ29kZSwgcHJvcGFnYXRpb24sIGRpYWcgfSA9IHJlcXVpcmUoJ0BvcGVudGVsZW1ldHJ5L2FwaScpXG5jb25zdCB7IGdldFJQQ01ldGFkYXRhLCBSUENUeXBlIH0gPSByZXF1aXJlKCdAb3BlbnRlbGVtZXRyeS9jb3JlJylcbmNvbnN0IHtcbiAgQVRUUl9IVFRQX1JPVVRFLFxuICBBVFRSX0hUVFBfUkVTUE9OU0VfU1RBVFVTX0NPREUsXG4gIEFUVFJfSFRUUF9SRVFVRVNUX01FVEhPRCxcbiAgQVRUUl9VUkxfUEFUSFxufSA9IHJlcXVpcmUoJ0BvcGVudGVsZW1ldHJ5L3NlbWFudGljLWNvbnZlbnRpb25zJylcbmNvbnN0IHsgSW5zdHJ1bWVudGF0aW9uQmFzZSB9ID0gcmVxdWlyZSgnQG9wZW50ZWxlbWV0cnkvaW5zdHJ1bWVudGF0aW9uJylcblxuY29uc3Qge1xuICB2ZXJzaW9uOiBQQUNLQUdFX1ZFUlNJT04sXG4gIG5hbWU6IFBBQ0tBR0VfTkFNRVxufSA9IHJlcXVpcmUoJy4vcGFja2FnZS5qc29uJylcblxuLy8gQ29uc3RhbnRzXG5jb25zdCBTVVBQT1JURURfVkVSU0lPTlMgPSAnPj00LjAuMCA8NidcbmNvbnN0IEZBU1RJRllfSE9PS1MgPSBbXG4gICdvblJlcXVlc3QnLFxuICAncHJlUGFyc2luZycsXG4gICdwcmVWYWxpZGF0aW9uJyxcbiAgJ3ByZUhhbmRsZXInLFxuICAncHJlU2VyaWFsaXphdGlvbicsXG4gICdvblNlbmQnLFxuICAnb25SZXNwb25zZScsXG4gICdvbkVycm9yJ1xuXVxuY29uc3QgQVRUUklCVVRFX05BTUVTID0ge1xuICBIT09LX05BTUU6ICdob29rLm5hbWUnLFxuICBGQVNUSUZZX1RZUEU6ICdmYXN0aWZ5LnR5cGUnLFxuICBIT09LX0NBTExCQUNLX05BTUU6ICdob29rLmNhbGxiYWNrLm5hbWUnLFxuICBST09UOiAnZmFzdGlmeS5yb290J1xufVxuY29uc3QgSE9PS19UWVBFUyA9IHtcbiAgUk9VVEU6ICdyb3V0ZS1ob29rJyxcbiAgSU5TVEFOQ0U6ICdob29rJyxcbiAgSEFORExFUjogJ3JlcXVlc3QtaGFuZGxlcidcbn1cbmNvbnN0IEFOT05ZTU9VU19GVU5DVElPTl9OQU1FID0gJ2Fub255bW91cydcblxuLy8gU3ltYm9sc1xuY29uc3Qga0luc3RydW1lbnRhdGlvbiA9IFN5bWJvbCgnZmFzdGlmeSBvdGVsIGluc3RhbmNlJylcbmNvbnN0IGtSZXF1ZXN0U3BhbiA9IFN5bWJvbCgnZmFzdGlmeSBvdGVsIHJlcXVlc3Qgc3BhbnMnKVxuY29uc3Qga1JlcXVlc3RDb250ZXh0ID0gU3ltYm9sKCdmYXN0aWZ5IG90ZWwgcmVxdWVzdCBjb250ZXh0JylcbmNvbnN0IGtBZGRIb29rT3JpZ2luYWwgPSBTeW1ib2woJ2Zhc3RpZnkgb3RlbCBhZGRob29rIG9yaWdpbmFsJylcbmNvbnN0IGtTZXROb3RGb3VuZE9yaWdpbmFsID0gU3ltYm9sKCdmYXN0aWZ5IG90ZWwgc2V0bm90Zm91bmQgb3JpZ2luYWwnKVxuY29uc3Qga0lnbm9yZVBhdGhzID0gU3ltYm9sKCdmYXN0aWZ5IG90ZWwgaWdub3JlIHBhdGgnKVxuY29uc3Qga1JlY29yZEV4Y2VwdGlvbnMgPSBTeW1ib2woJ2Zhc3RpZnkgb3RlbCByZWNvcmQgZXhjZXB0aW9ucycpXG5cbmNsYXNzIEZhc3RpZnlPdGVsSW5zdHJ1bWVudGF0aW9uIGV4dGVuZHMgSW5zdHJ1bWVudGF0aW9uQmFzZSB7XG4gIGxvZ2dlciA9IG51bGxcbiAgX3JlcXVlc3RIb29rID0gbnVsbFxuICBfbGlmZWN5Y2xlSG9vayA9IG51bGxcblxuICBjb25zdHJ1Y3RvciAoY29uZmlnKSB7XG4gICAgc3VwZXIoUEFDS0FHRV9OQU1FLCBQQUNLQUdFX1ZFUlNJT04sIGNvbmZpZylcbiAgICB0aGlzLmxvZ2dlciA9IGRpYWcuY3JlYXRlQ29tcG9uZW50TG9nZ2VyKHsgbmFtZXNwYWNlOiBQQUNLQUdFX05BTUUgfSlcbiAgICB0aGlzW2tJZ25vcmVQYXRoc10gPSBudWxsXG4gICAgdGhpc1trUmVjb3JkRXhjZXB0aW9uc10gPSB0cnVlXG5cbiAgICBpZiAoY29uZmlnPy5yZWNvcmRFeGNlcHRpb25zICE9IG51bGwpIHtcbiAgICAgIGlmICh0eXBlb2YgY29uZmlnLnJlY29yZEV4Y2VwdGlvbnMgIT09ICdib29sZWFuJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdyZWNvcmRFeGNlcHRpb25zIG11c3QgYmUgYSBib29sZWFuJylcbiAgICAgIH1cblxuICAgICAgdGhpc1trUmVjb3JkRXhjZXB0aW9uc10gPSBjb25maWcucmVjb3JkRXhjZXB0aW9uc1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGNvbmZpZz8ucmVxdWVzdEhvb2sgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRoaXMuX3JlcXVlc3RIb29rID0gY29uZmlnLnJlcXVlc3RIb29rXG4gICAgfVxuICAgIGlmICh0eXBlb2YgY29uZmlnPy5saWZlY3ljbGVIb29rID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aGlzLl9saWZlY3ljbGVIb29rID0gY29uZmlnLmxpZmVjeWNsZUhvb2tcbiAgICB9XG5cbiAgICBpZiAoY29uZmlnPy5pZ25vcmVQYXRocyAhPSBudWxsIHx8IHByb2Nlc3MuZW52Lk9URUxfRkFTVElGWV9JR05PUkVfUEFUSFMgIT0gbnVsbCkge1xuICAgICAgY29uc3QgaWdub3JlUGF0aHMgPSBjb25maWc/Lmlnbm9yZVBhdGhzID8/IHByb2Nlc3MuZW52Lk9URUxfRkFTVElGWV9JR05PUkVfUEFUSFNcblxuICAgICAgaWYgKCh0eXBlb2YgaWdub3JlUGF0aHMgIT09ICdzdHJpbmcnIHx8IGlnbm9yZVBhdGhzLmxlbmd0aCA9PT0gMCkgJiYgdHlwZW9mIGlnbm9yZVBhdGhzICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgJ2lnbm9yZVBhdGhzIG11c3QgYmUgYSBzdHJpbmcgb3IgYSBmdW5jdGlvbidcbiAgICAgICAgKVxuICAgICAgfVxuXG4gICAgICBsZXQgZ2xvYk1hdGNoZXIgPSBudWxsXG5cbiAgICAgIHRoaXNba0lnbm9yZVBhdGhzXSA9IChyb3V0ZU9wdGlvbnMpID0+IHtcbiAgICAgICAgaWYgKHR5cGVvZiBpZ25vcmVQYXRocyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIHJldHVybiBpZ25vcmVQYXRocyhyb3V0ZU9wdGlvbnMpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gVXNpbmcgbWluaW1hdGNoIHRvIG1hdGNoIHRoZSBwYXRoIHVudGlsIHBhdGgubWF0Y2hlc0dsb2IgaXMgb3V0IG9mIGV4cGVyaW1lbnRhbFxuICAgICAgICAgIC8vIHBhdGgubWF0Y2hlc0dsb2IgdXNlcyBtaW5pbWF0Y2ggaW50ZXJuYWxseVxuICAgICAgICAgIGlmIChnbG9iTWF0Y2hlciA9PSBudWxsKSB7XG4gICAgICAgICAgICBnbG9iTWF0Y2hlciA9IHJlcXVpcmUoJ21pbmltYXRjaCcpLm1pbmltYXRjaFxuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBnbG9iTWF0Y2hlcihyb3V0ZU9wdGlvbnMudXJsLCBpZ25vcmVQYXRocylcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGVuYWJsZSAoKSB7XG4gICAgaWYgKHRoaXMuX2hhbmRsZUluaXRpYWxpemF0aW9uID09PSB1bmRlZmluZWQgJiYgdGhpcy5nZXRDb25maWcoKS5yZWdpc3Rlck9uSW5pdGlhbGl6YXRpb24pIHtcbiAgICAgIHRoaXMuX2hhbmRsZUluaXRpYWxpemF0aW9uID0gKG1lc3NhZ2UpID0+IHtcbiAgICAgICAgLy8gQ2Fubm90IHVzZSBgZmFzdGlmeS5yZWdpc3RlcihwbHVnaW4pYCBiZWNhdXNlIGl0IGlzIGxhemlseSBleGVjdXRlZCBhbmRcbiAgICAgICAgLy8gdGh1cyByZXF1aXJlcyB1c2VyIGNvZGUgdG8gYXdhaXQgZmFzdGlmeSBpbnN0YW5jZSBmaXJzdC5cbiAgICAgICAgdGhpcy5wbHVnaW4oKShtZXNzYWdlLmZhc3RpZnksIHVuZGVmaW5lZCwgKCkgPT4ge30pXG5cbiAgICAgICAgLy8gQWRkIGFuIGVtcHR5IHBsdWdpbiB0byBrZWVwIGBhcHAuaGFzUGx1Z2luKCdAZmFzdGlmeS9vdGVsJylgIGludmFyaWFudFxuICAgICAgICBjb25zdCBlbXB0eVBsdWdpbiA9IChfLCBfXywgZG9uZSkgPT4ge1xuICAgICAgICAgIGRvbmUoKVxuICAgICAgICB9XG4gICAgICAgIGVtcHR5UGx1Z2luW1N5bWJvbC5mb3IoJ3NraXAtb3ZlcnJpZGUnKV0gPSB0cnVlXG4gICAgICAgIGVtcHR5UGx1Z2luW1N5bWJvbC5mb3IoJ2Zhc3RpZnkuZGlzcGxheS1uYW1lJyldID0gJ0BmYXN0aWZ5L290ZWwnXG4gICAgICAgIG1lc3NhZ2UuZmFzdGlmeS5yZWdpc3RlcihlbXB0eVBsdWdpbilcbiAgICAgIH1cbiAgICAgIGRjLnN1YnNjcmliZSgnZmFzdGlmeS5pbml0aWFsaXphdGlvbicsIHRoaXMuX2hhbmRsZUluaXRpYWxpemF0aW9uKVxuICAgIH1cbiAgICByZXR1cm4gc3VwZXIuZW5hYmxlKClcbiAgfVxuXG4gIGRpc2FibGUgKCkge1xuICAgIGlmICh0aGlzLl9oYW5kbGVJbml0aWFsaXphdGlvbikge1xuICAgICAgZGMudW5zdWJzY3JpYmUoJ2Zhc3RpZnkuaW5pdGlhbGl6YXRpb24nLCB0aGlzLl9oYW5kbGVJbml0aWFsaXphdGlvbilcbiAgICAgIHRoaXMuX2hhbmRsZUluaXRpYWxpemF0aW9uID0gdW5kZWZpbmVkXG4gICAgfVxuICAgIHJldHVybiBzdXBlci5kaXNhYmxlKClcbiAgfVxuXG4gIC8vIFdlIGRvIG5vdCBkbyBwYXRjaGluZyBpbiB0aGlzIGluc3RydW1lbnRhdGlvblxuICBpbml0ICgpIHtcbiAgICByZXR1cm4gW11cbiAgfVxuXG4gIHBsdWdpbiAoKSB7XG4gICAgY29uc3QgaW5zdHJ1bWVudGF0aW9uID0gdGhpc1xuXG4gICAgRmFzdGlmeUluc3RydW1lbnRhdGlvblBsdWdpbltTeW1ib2wuZm9yKCdza2lwLW92ZXJyaWRlJyldID0gdHJ1ZVxuICAgIEZhc3RpZnlJbnN0cnVtZW50YXRpb25QbHVnaW5bU3ltYm9sLmZvcignZmFzdGlmeS5kaXNwbGF5LW5hbWUnKV0gPSAnQGZhc3RpZnkvb3RlbCdcbiAgICBGYXN0aWZ5SW5zdHJ1bWVudGF0aW9uUGx1Z2luW1N5bWJvbC5mb3IoJ3BsdWdpbi1tZXRhJyldID0ge1xuICAgICAgZmFzdGlmeTogU1VQUE9SVEVEX1ZFUlNJT05TLFxuICAgICAgbmFtZTogJ0BmYXN0aWZ5L290ZWwnLFxuICAgIH1cblxuICAgIHJldHVybiBGYXN0aWZ5SW5zdHJ1bWVudGF0aW9uUGx1Z2luXG5cbiAgICBmdW5jdGlvbiBGYXN0aWZ5SW5zdHJ1bWVudGF0aW9uUGx1Z2luIChpbnN0YW5jZSwgb3B0cywgZG9uZSkge1xuICAgICAgaW5zdGFuY2UuZGVjb3JhdGUoa0luc3RydW1lbnRhdGlvbiwgaW5zdHJ1bWVudGF0aW9uKVxuICAgICAgLy8gYWRkSG9vayBhbmQgbm90Zm91bmRIYW5kbGVyIGFyZSBlc3NlbnRpYWxseSBpbmhlcml0ZWQgZnJvbSB0aGUgcHJvdG90eXBlXG4gICAgICAvLyB3aGF0IGlzIGltcG9ydGFudCBpcyB0byBib3VuZCBpdCB0byB0aGUgcmlnaHQgaW5zdGFuY2VcbiAgICAgIGluc3RhbmNlLmRlY29yYXRlKGtBZGRIb29rT3JpZ2luYWwsIGluc3RhbmNlLmFkZEhvb2spXG4gICAgICBpbnN0YW5jZS5kZWNvcmF0ZShrU2V0Tm90Rm91bmRPcmlnaW5hbCwgaW5zdGFuY2Uuc2V0Tm90Rm91bmRIYW5kbGVyKVxuICAgICAgaW5zdGFuY2UuZGVjb3JhdGVSZXF1ZXN0KCdvcGVudGVsZW1ldHJ5JywgZnVuY3Rpb24gb3BlbmV0ZWxlbWV0cnkgKCkge1xuICAgICAgICBjb25zdCBjdHggPSB0aGlzW2tSZXF1ZXN0Q29udGV4dF1cbiAgICAgICAgY29uc3Qgc3BhbiA9IHRoaXNba1JlcXVlc3RTcGFuXVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgZW5hYmxlZDogdGhpcy5yb3V0ZU9wdGlvbnMuY29uZmlnPy5vdGVsICE9PSBmYWxzZSxcbiAgICAgICAgICBzcGFuLFxuICAgICAgICAgIHRyYWNlcjogaW5zdHJ1bWVudGF0aW9uLnRyYWNlcixcbiAgICAgICAgICBjb250ZXh0OiBjdHgsXG4gICAgICAgICAgaW5qZWN0OiAoY2Fycmllciwgc2V0dGVyKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gcHJvcGFnYXRpb24uaW5qZWN0KGN0eCwgY2Fycmllciwgc2V0dGVyKVxuICAgICAgICAgIH0sXG4gICAgICAgICAgZXh0cmFjdDogKGNhcnJpZXIsIGdldHRlcikgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHByb3BhZ2F0aW9uLmV4dHJhY3QoY3R4LCBjYXJyaWVyLCBnZXR0ZXIpXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgaW5zdGFuY2UuZGVjb3JhdGVSZXF1ZXN0KGtSZXF1ZXN0U3BhbiwgbnVsbClcbiAgICAgIGluc3RhbmNlLmRlY29yYXRlUmVxdWVzdChrUmVxdWVzdENvbnRleHQsIG51bGwpXG5cbiAgICAgIGluc3RhbmNlLmFkZEhvb2soJ29uUm91dGUnLCBmdW5jdGlvbiBvdGVsV2lyZVJvdXRlIChyb3V0ZU9wdGlvbnMpIHtcbiAgICAgICAgaWYgKGluc3RydW1lbnRhdGlvbltrSWdub3JlUGF0aHNdPy4ocm91dGVPcHRpb25zKSA9PT0gdHJ1ZSkge1xuICAgICAgICAgIGluc3RydW1lbnRhdGlvbi5sb2dnZXIuZGVidWcoXG4gICAgICAgICAgICBgSWdub3Jpbmcgcm91dGUgaW5zdHJ1bWVudGF0aW9uICR7cm91dGVPcHRpb25zLm1ldGhvZH0gJHtyb3V0ZU9wdGlvbnMudXJsfSBiZWNhdXNlIGl0IG1hdGNoZXMgdGhlIGlnbm9yZSBwYXRoYFxuICAgICAgICAgIClcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChyb3V0ZU9wdGlvbnMuY29uZmlnPy5vdGVsID09PSBmYWxzZSkge1xuICAgICAgICAgIGluc3RydW1lbnRhdGlvbi5sb2dnZXIuZGVidWcoXG4gICAgICAgICAgICBgSWdub3Jpbmcgcm91dGUgaW5zdHJ1bWVudGF0aW9uICR7cm91dGVPcHRpb25zLm1ldGhvZH0gJHtyb3V0ZU9wdGlvbnMudXJsfSBiZWNhdXNlIGl0IGlzIGRpc2FibGVkYFxuICAgICAgICAgIClcblxuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChjb25zdCBob29rIG9mIEZBU1RJRllfSE9PS1MpIHtcbiAgICAgICAgICBpZiAocm91dGVPcHRpb25zW2hvb2tdICE9IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnN0IGhhbmRsZXJMaWtlID0gcm91dGVPcHRpb25zW2hvb2tdXG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgaGFuZGxlckxpa2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgcm91dGVPcHRpb25zW2hvb2tdID0gaGFuZGxlcldyYXBwZXIoaGFuZGxlckxpa2UsIGhvb2ssIHtcbiAgICAgICAgICAgICAgICBbQVRUUklCVVRFX05BTUVTLkhPT0tfTkFNRV06IGAke3RoaXMucGx1Z2luTmFtZX0gLSByb3V0ZSAtPiAke2hvb2t9YCxcbiAgICAgICAgICAgICAgICBbQVRUUklCVVRFX05BTUVTLkZBU1RJRllfVFlQRV06IEhPT0tfVFlQRVMuUk9VVEUsXG4gICAgICAgICAgICAgICAgW0FUVFJfSFRUUF9ST1VURV06IHJvdXRlT3B0aW9ucy51cmwsXG4gICAgICAgICAgICAgICAgW0FUVFJJQlVURV9OQU1FUy5IT09LX0NBTExCQUNLX05BTUVdOlxuICAgICAgICAgICAgICAgICAgaGFuZGxlckxpa2UubmFtZT8ubGVuZ3RoID4gMFxuICAgICAgICAgICAgICAgICAgICA/IGhhbmRsZXJMaWtlLm5hbWVcbiAgICAgICAgICAgICAgICAgICAgOiBBTk9OWU1PVVNfRlVOQ1RJT05fTkFNRSAvKiBjOCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KGhhbmRsZXJMaWtlKSkge1xuICAgICAgICAgICAgICBjb25zdCB3cmFwcGVkSGFuZGxlcnMgPSBbXVxuXG4gICAgICAgICAgICAgIGZvciAoY29uc3QgaGFuZGxlciBvZiBoYW5kbGVyTGlrZSkge1xuICAgICAgICAgICAgICAgIHdyYXBwZWRIYW5kbGVycy5wdXNoKFxuICAgICAgICAgICAgICAgICAgaGFuZGxlcldyYXBwZXIoaGFuZGxlciwgaG9vaywge1xuICAgICAgICAgICAgICAgICAgICBbQVRUUklCVVRFX05BTUVTLkhPT0tfTkFNRV06IGAke3RoaXMucGx1Z2luTmFtZX0gLSByb3V0ZSAtPiAke2hvb2t9YCxcbiAgICAgICAgICAgICAgICAgICAgW0FUVFJJQlVURV9OQU1FUy5GQVNUSUZZX1RZUEVdOiBIT09LX1RZUEVTLlJPVVRFLFxuICAgICAgICAgICAgICAgICAgICBbQVRUUl9IVFRQX1JPVVRFXTogcm91dGVPcHRpb25zLnVybCxcbiAgICAgICAgICAgICAgICAgICAgW0FUVFJJQlVURV9OQU1FUy5IT09LX0NBTExCQUNLX05BTUVdOlxuICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZXIubmFtZT8ubGVuZ3RoID4gMFxuICAgICAgICAgICAgICAgICAgICAgICAgPyBoYW5kbGVyLm5hbWVcbiAgICAgICAgICAgICAgICAgICAgICAgIDogQU5PTllNT1VTX0ZVTkNUSU9OX05BTUVcbiAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgcm91dGVPcHRpb25zW2hvb2tdID0gd3JhcHBlZEhhbmRsZXJzXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gV2UgYWx3YXlzIHdhbnQgdG8gYWRkIHRoZSBvblNlbmQgaG9vayB0byB0aGUgcm91dGUgdG8gYmUgZXhlY3V0ZWQgbGFzdFxuICAgICAgICBpZiAocm91dGVPcHRpb25zLm9uU2VuZCAhPSBudWxsKSB7XG4gICAgICAgICAgcm91dGVPcHRpb25zLm9uU2VuZCA9IEFycmF5LmlzQXJyYXkocm91dGVPcHRpb25zLm9uU2VuZClcbiAgICAgICAgICAgID8gWy4uLnJvdXRlT3B0aW9ucy5vblNlbmQsIGZpbmFsaXplUmVzcG9uc2VTcGFuSG9va11cbiAgICAgICAgICAgIDogW3JvdXRlT3B0aW9ucy5vblNlbmQsIGZpbmFsaXplUmVzcG9uc2VTcGFuSG9va11cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByb3V0ZU9wdGlvbnMub25TZW5kID0gZmluYWxpemVSZXNwb25zZVNwYW5Ib29rXG4gICAgICAgIH1cblxuICAgICAgICAvLyBXZSBhbHdheXMgd2FudCB0byBhZGQgdGhlIG9uRXJyb3IgaG9vayB0byB0aGUgcm91dGUgdG8gYmUgZXhlY3V0ZWQgbGFzdFxuICAgICAgICBpZiAocm91dGVPcHRpb25zLm9uRXJyb3IgIT0gbnVsbCkge1xuICAgICAgICAgIHJvdXRlT3B0aW9ucy5vbkVycm9yID0gQXJyYXkuaXNBcnJheShyb3V0ZU9wdGlvbnMub25FcnJvcilcbiAgICAgICAgICAgID8gWy4uLnJvdXRlT3B0aW9ucy5vbkVycm9yLCByZWNvcmRFcnJvckluU3Bhbkhvb2tdXG4gICAgICAgICAgICA6IFtyb3V0ZU9wdGlvbnMub25FcnJvciwgcmVjb3JkRXJyb3JJblNwYW5Ib29rXVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJvdXRlT3B0aW9ucy5vbkVycm9yID0gcmVjb3JkRXJyb3JJblNwYW5Ib29rXG4gICAgICAgIH1cblxuICAgICAgICByb3V0ZU9wdGlvbnMuaGFuZGxlciA9IGhhbmRsZXJXcmFwcGVyKHJvdXRlT3B0aW9ucy5oYW5kbGVyLCAnaGFuZGxlcicsIHtcbiAgICAgICAgICBbQVRUUklCVVRFX05BTUVTLkhPT0tfTkFNRV06IGAke3RoaXMucGx1Z2luTmFtZX0gLSByb3V0ZS1oYW5kbGVyYCxcbiAgICAgICAgICBbQVRUUklCVVRFX05BTUVTLkZBU1RJRllfVFlQRV06IEhPT0tfVFlQRVMuSEFORExFUixcbiAgICAgICAgICBbQVRUUl9IVFRQX1JPVVRFXTogcm91dGVPcHRpb25zLnVybCxcbiAgICAgICAgICBbQVRUUklCVVRFX05BTUVTLkhPT0tfQ0FMTEJBQ0tfTkFNRV06XG4gICAgICAgICAgICByb3V0ZU9wdGlvbnMuaGFuZGxlci5uYW1lLmxlbmd0aCA+IDBcbiAgICAgICAgICAgICAgPyByb3V0ZU9wdGlvbnMuaGFuZGxlci5uYW1lXG4gICAgICAgICAgICAgIDogQU5PTllNT1VTX0ZVTkNUSU9OX05BTUVcbiAgICAgICAgfSlcbiAgICAgIH0pXG5cbiAgICAgIGluc3RhbmNlLmFkZEhvb2soJ29uUmVxdWVzdCcsIGZ1bmN0aW9uIHN0YXJ0UmVxdWVzdFNwYW5Ib29rIChyZXF1ZXN0LCBfcmVwbHksIGhvb2tEb25lKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICB0aGlzW2tJbnN0cnVtZW50YXRpb25dLmlzRW5hYmxlZCgpID09PSBmYWxzZSB8fFxuICAgICAgICAgIHJlcXVlc3Qucm91dGVPcHRpb25zLmNvbmZpZz8ub3RlbCA9PT0gZmFsc2VcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuIGhvb2tEb25lKClcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzW2tJbnN0cnVtZW50YXRpb25dW2tJZ25vcmVQYXRoc10/Lih7XG4gICAgICAgICAgdXJsOiByZXF1ZXN0LnVybCxcbiAgICAgICAgICBtZXRob2Q6IHJlcXVlc3QubWV0aG9kLFxuICAgICAgICB9KSA9PT0gdHJ1ZSkge1xuICAgICAgICAgIHRoaXNba0luc3RydW1lbnRhdGlvbl0ubG9nZ2VyLmRlYnVnKFxuICAgICAgICAgICAgYElnbm9yaW5nIHJlcXVlc3QgJHtyZXF1ZXN0Lm1ldGhvZH0gJHtyZXF1ZXN0LnVybH0gYmVjYXVzZSBpdCBtYXRjaGVzIHRoZSBpZ25vcmUgcGF0aGBcbiAgICAgICAgICApXG4gICAgICAgICAgcmV0dXJuIGhvb2tEb25lKClcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBjdHggPSBjb250ZXh0LmFjdGl2ZSgpXG5cbiAgICAgICAgaWYgKHRyYWNlLmdldFNwYW4oY3R4KSA9PSBudWxsKSB7XG4gICAgICAgICAgY3R4ID0gcHJvcGFnYXRpb24uZXh0cmFjdChjdHgsIHJlcXVlc3QuaGVhZGVycylcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJwY01ldGFkYXRhID0gZ2V0UlBDTWV0YWRhdGEoY3R4KVxuXG4gICAgICAgIGlmIChcbiAgICAgICAgICByZXF1ZXN0LnJvdXRlT3B0aW9ucy51cmwgIT0gbnVsbCAmJlxuICAgICAgICAgIHJwY01ldGFkYXRhPy50eXBlID09PSBSUENUeXBlLkhUVFBcbiAgICAgICAgKSB7XG4gICAgICAgICAgcnBjTWV0YWRhdGEucm91dGUgPSByZXF1ZXN0LnJvdXRlT3B0aW9ucy51cmxcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGF0dHJpYnV0ZXMgPSB7XG4gICAgICAgICAgW0FUVFJJQlVURV9OQU1FUy5ST09UXTogJ0BmYXN0aWZ5L290ZWwnLFxuICAgICAgICAgIFtBVFRSX0hUVFBfUkVRVUVTVF9NRVRIT0RdOiByZXF1ZXN0Lm1ldGhvZCxcbiAgICAgICAgICBbQVRUUl9VUkxfUEFUSF06IHJlcXVlc3QudXJsXG4gICAgICAgIH1cblxuICAgICAgICBpZiAocmVxdWVzdC5yb3V0ZU9wdGlvbnMudXJsICE9IG51bGwpIHtcbiAgICAgICAgICBhdHRyaWJ1dGVzW0FUVFJfSFRUUF9ST1VURV0gPSByZXF1ZXN0LnJvdXRlT3B0aW9ucy51cmxcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KCdAb3BlbnRlbGVtZXRyeS9hcGknKS5TcGFufSAqL1xuICAgICAgICBjb25zdCBzcGFuID0gdGhpc1trSW5zdHJ1bWVudGF0aW9uXS50cmFjZXIuc3RhcnRTcGFuKCdyZXF1ZXN0Jywge1xuICAgICAgICAgIGF0dHJpYnV0ZXNcbiAgICAgICAgfSwgY3R4KVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdGhpc1trSW5zdHJ1bWVudGF0aW9uXS5fcmVxdWVzdEhvb2s/LihzcGFuLCByZXF1ZXN0KVxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICB0aGlzW2tJbnN0cnVtZW50YXRpb25dLmxvZ2dlci5lcnJvcih7IGVyciB9LCAncmVxdWVzdEhvb2sgdGhyZXcnKVxuICAgICAgICB9XG5cbiAgICAgICAgcmVxdWVzdFtrUmVxdWVzdENvbnRleHRdID0gdHJhY2Uuc2V0U3BhbihjdHgsIHNwYW4pXG4gICAgICAgIHJlcXVlc3Rba1JlcXVlc3RTcGFuXSA9IHNwYW5cblxuICAgICAgICBjb250ZXh0LndpdGgocmVxdWVzdFtrUmVxdWVzdENvbnRleHRdLCAoKSA9PiB7XG4gICAgICAgICAgaG9va0RvbmUoKVxuICAgICAgICB9KVxuICAgICAgfSlcblxuICAgICAgLy8gb25SZXNwb25zZSBpcyB0aGUgbGFzdCBob29rIHRvIGJlIGV4ZWN1dGVkLCBvbmx5IGFkZGVkIGZvciA0MDQgaGFuZGxlcnNcbiAgICAgIGluc3RhbmNlLmFkZEhvb2soJ29uUmVzcG9uc2UnLCBmdW5jdGlvbiBmaW5hbGl6ZU5vdEZvdW5kU3Bhbkhvb2sgKHJlcXVlc3QsIHJlcGx5LCBob29rRG9uZSkge1xuICAgICAgICBjb25zdCBzcGFuID0gcmVxdWVzdFtrUmVxdWVzdFNwYW5dXG5cbiAgICAgICAgaWYgKHNwYW4gIT0gbnVsbCkge1xuICAgICAgICAgIHNwYW4uc2V0QXR0cmlidXRlcyh7XG4gICAgICAgICAgICBbQVRUUl9IVFRQX1JFU1BPTlNFX1NUQVRVU19DT0RFXTogcmVwbHkuc3RhdHVzQ29kZVxuICAgICAgICAgIH0pXG4gICAgICAgICAgc3Bhbi5lbmQoKVxuICAgICAgICB9XG5cbiAgICAgICAgcmVxdWVzdFtrUmVxdWVzdFNwYW5dID0gbnVsbFxuXG4gICAgICAgIGhvb2tEb25lKClcbiAgICAgIH0pXG5cbiAgICAgIGluc3RhbmNlLmFkZEhvb2sgPSBhZGRIb29rUGF0Y2hlZFxuICAgICAgaW5zdGFuY2Uuc2V0Tm90Rm91bmRIYW5kbGVyID0gc2V0Tm90Rm91bmRIYW5kbGVyUGF0Y2hlZFxuXG4gICAgICBkb25lKClcblxuICAgICAgZnVuY3Rpb24gZmluYWxpemVSZXNwb25zZVNwYW5Ib29rIChyZXF1ZXN0LCByZXBseSwgcGF5bG9hZCwgaG9va0RvbmUpIHtcbiAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoJ0BvcGVudGVsZW1ldHJ5L2FwaScpLlNwYW59ICovXG4gICAgICAgIGNvbnN0IHNwYW4gPSByZXF1ZXN0W2tSZXF1ZXN0U3Bhbl1cblxuICAgICAgICBpZiAoc3BhbiAhPSBudWxsKSB7XG4gICAgICAgICAgaWYgKHJlcGx5LnN0YXR1c0NvZGUgPj0gNTAwKSB7XG4gICAgICAgICAgICBzcGFuLnNldFN0YXR1cyh7IGNvZGU6IFNwYW5TdGF0dXNDb2RlLkVSUk9SIH0pXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGVzKHtcbiAgICAgICAgICAgIFtBVFRSX0hUVFBfUkVTUE9OU0VfU1RBVFVTX0NPREVdOiByZXBseS5zdGF0dXNDb2RlXG4gICAgICAgICAgfSlcbiAgICAgICAgICBzcGFuLmVuZCgpXG4gICAgICAgIH1cblxuICAgICAgICByZXF1ZXN0W2tSZXF1ZXN0U3Bhbl0gPSBudWxsXG5cbiAgICAgICAgaG9va0RvbmUobnVsbCwgcGF5bG9hZClcbiAgICAgIH1cblxuICAgICAgZnVuY3Rpb24gcmVjb3JkRXJyb3JJblNwYW5Ib29rIChyZXF1ZXN0LCByZXBseSwgZXJyb3IsIGhvb2tEb25lKSB7XG4gICAgICAgIC8qKiBAdHlwZSB7U3Bhbn0gKi9cbiAgICAgICAgY29uc3Qgc3BhbiA9IHJlcXVlc3Rba1JlcXVlc3RTcGFuXVxuXG4gICAgICAgIGlmIChzcGFuICE9IG51bGwpIHtcbiAgICAgICAgICBzcGFuLnNldFN0YXR1cyh7XG4gICAgICAgICAgICBjb2RlOiBTcGFuU3RhdHVzQ29kZS5FUlJPUixcbiAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2VcbiAgICAgICAgICB9KVxuICAgICAgICAgIGlmIChpbnN0cnVtZW50YXRpb25ba1JlY29yZEV4Y2VwdGlvbnNdICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgc3Bhbi5yZWNvcmRFeGNlcHRpb24oZXJyb3IpXG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaG9va0RvbmUoKVxuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiBhZGRIb29rUGF0Y2hlZCAobmFtZSwgaG9vaykge1xuICAgICAgICBjb25zdCBhZGRIb29rT3JpZ2luYWwgPSB0aGlzW2tBZGRIb29rT3JpZ2luYWxdXG5cbiAgICAgICAgaWYgKEZBU1RJRllfSE9PS1MuaW5jbHVkZXMobmFtZSkpIHtcbiAgICAgICAgICByZXR1cm4gYWRkSG9va09yaWdpbmFsLmNhbGwoXG4gICAgICAgICAgICB0aGlzLFxuICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgIGhhbmRsZXJXcmFwcGVyKGhvb2ssIG5hbWUsIHtcbiAgICAgICAgICAgICAgW0FUVFJJQlVURV9OQU1FUy5IT09LX05BTUVdOiBgJHt0aGlzLnBsdWdpbk5hbWV9IC0gJHtuYW1lfWAsXG4gICAgICAgICAgICAgIFtBVFRSSUJVVEVfTkFNRVMuRkFTVElGWV9UWVBFXTogSE9PS19UWVBFUy5JTlNUQU5DRSxcbiAgICAgICAgICAgICAgW0FUVFJJQlVURV9OQU1FUy5IT09LX0NBTExCQUNLX05BTUVdOlxuICAgICAgICAgICAgICAgIGhvb2submFtZT8ubGVuZ3RoID4gMFxuICAgICAgICAgICAgICAgICAgPyBob29rLm5hbWVcbiAgICAgICAgICAgICAgICAgIDogQU5PTllNT1VTX0ZVTkNUSU9OX05BTUUgLyogYzggaWdub3JlIG5leHQgKi9cbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBhZGRIb29rT3JpZ2luYWwuY2FsbCh0aGlzLCBuYW1lLCBob29rKVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIHNldE5vdEZvdW5kSGFuZGxlclBhdGNoZWQgKGhvb2tzLCBoYW5kbGVyKSB7XG4gICAgICAgIGNvbnN0IHNldE5vdEZvdW5kSGFuZGxlck9yaWdpbmFsID0gdGhpc1trU2V0Tm90Rm91bmRPcmlnaW5hbF1cbiAgICAgICAgaWYgKHR5cGVvZiBob29rcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIGhhbmRsZXIgPSBoYW5kbGVyV3JhcHBlcihob29rcywgJ25vdEZvdW5kSGFuZGxlcicsIHtcbiAgICAgICAgICAgIFtBVFRSSUJVVEVfTkFNRVMuSE9PS19OQU1FXTogYCR7dGhpcy5wbHVnaW5OYW1lfSAtIG5vdC1mb3VuZC1oYW5kbGVyYCxcbiAgICAgICAgICAgIFtBVFRSSUJVVEVfTkFNRVMuRkFTVElGWV9UWVBFXTogSE9PS19UWVBFUy5JTlNUQU5DRSxcbiAgICAgICAgICAgIFtBVFRSSUJVVEVfTkFNRVMuSE9PS19DQUxMQkFDS19OQU1FXTpcbiAgICAgICAgICAgICAgaG9va3MubmFtZT8ubGVuZ3RoID4gMFxuICAgICAgICAgICAgICAgID8gaG9va3MubmFtZVxuICAgICAgICAgICAgICAgIDogQU5PTllNT1VTX0ZVTkNUSU9OX05BTUUgLyogYzggaWdub3JlIG5leHQgKi9cbiAgICAgICAgICB9KVxuICAgICAgICAgIHNldE5vdEZvdW5kSGFuZGxlck9yaWdpbmFsLmNhbGwodGhpcywgaGFuZGxlcilcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoaG9va3MucHJlVmFsaWRhdGlvbiAhPSBudWxsKSB7XG4gICAgICAgICAgICBob29rcy5wcmVWYWxpZGF0aW9uID0gaGFuZGxlcldyYXBwZXIoaG9va3MucHJlVmFsaWRhdGlvbiwgJ25vdEZvdW5kSGFuZGxlciAtIHByZVZhbGlkYXRpb24nLCB7XG4gICAgICAgICAgICAgIFtBVFRSSUJVVEVfTkFNRVMuSE9PS19OQU1FXTogYCR7dGhpcy5wbHVnaW5OYW1lfSAtIG5vdC1mb3VuZC1oYW5kbGVyIC0gcHJlVmFsaWRhdGlvbmAsXG4gICAgICAgICAgICAgIFtBVFRSSUJVVEVfTkFNRVMuRkFTVElGWV9UWVBFXTogSE9PS19UWVBFUy5JTlNUQU5DRSxcbiAgICAgICAgICAgICAgW0FUVFJJQlVURV9OQU1FUy5IT09LX0NBTExCQUNLX05BTUVdOlxuICAgICAgICAgICAgICAgIGhvb2tzLnByZVZhbGlkYXRpb24ubmFtZT8ubGVuZ3RoID4gMFxuICAgICAgICAgICAgICAgICAgPyBob29rcy5wcmVWYWxpZGF0aW9uLm5hbWVcbiAgICAgICAgICAgICAgICAgIDogQU5PTllNT1VTX0ZVTkNUSU9OX05BTUUgLyogYzggaWdub3JlIG5leHQgKi9cbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGhvb2tzLnByZUhhbmRsZXIgIT0gbnVsbCkge1xuICAgICAgICAgICAgaG9va3MucHJlSGFuZGxlciA9IGhhbmRsZXJXcmFwcGVyKGhvb2tzLnByZUhhbmRsZXIsICdub3RGb3VuZEhhbmRsZXIgLSBwcmVIYW5kbGVyJywge1xuICAgICAgICAgICAgICBbQVRUUklCVVRFX05BTUVTLkhPT0tfTkFNRV06IGAke3RoaXMucGx1Z2luTmFtZX0gLSBub3QtZm91bmQtaGFuZGxlciAtIHByZUhhbmRsZXJgLFxuICAgICAgICAgICAgICBbQVRUUklCVVRFX05BTUVTLkZBU1RJRllfVFlQRV06IEhPT0tfVFlQRVMuSU5TVEFOQ0UsXG4gICAgICAgICAgICAgIFtBVFRSSUJVVEVfTkFNRVMuSE9PS19DQUxMQkFDS19OQU1FXTpcbiAgICAgICAgICAgICAgICBob29rcy5wcmVIYW5kbGVyLm5hbWU/Lmxlbmd0aCA+IDBcbiAgICAgICAgICAgICAgICAgID8gaG9va3MucHJlSGFuZGxlci5uYW1lXG4gICAgICAgICAgICAgICAgICA6IEFOT05ZTU9VU19GVU5DVElPTl9OQU1FIC8qIGM4IGlnbm9yZSBuZXh0ICovXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGhhbmRsZXIgPSBoYW5kbGVyV3JhcHBlcihoYW5kbGVyLCAnbm90Rm91bmRIYW5kbGVyJywge1xuICAgICAgICAgICAgW0FUVFJJQlVURV9OQU1FUy5IT09LX05BTUVdOiBgJHt0aGlzLnBsdWdpbk5hbWV9IC0gbm90LWZvdW5kLWhhbmRsZXJgLFxuICAgICAgICAgICAgW0FUVFJJQlVURV9OQU1FUy5GQVNUSUZZX1RZUEVdOiBIT09LX1RZUEVTLklOU1RBTkNFLFxuICAgICAgICAgICAgW0FUVFJJQlVURV9OQU1FUy5IT09LX0NBTExCQUNLX05BTUVdOlxuICAgICAgICAgICAgICBoYW5kbGVyLm5hbWU/Lmxlbmd0aCA+IDBcbiAgICAgICAgICAgICAgICA/IGhhbmRsZXIubmFtZVxuICAgICAgICAgICAgICAgIDogQU5PTllNT1VTX0ZVTkNUSU9OX05BTUUgLyogYzggaWdub3JlIG5leHQgKi9cbiAgICAgICAgICB9KVxuICAgICAgICAgIHNldE5vdEZvdW5kSGFuZGxlck9yaWdpbmFsLmNhbGwodGhpcywgaG9va3MsIGhhbmRsZXIpXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gcmVndWxhciBoYW5kbGVycyBhcmUgKHJlcXVlc3QsIHJlcGx5KSwgQGZhc3RpZnkvd2Vic29ja2V0IGhhbmRsZXJzIGFyZSAoc29ja2V0LCByZXF1ZXN0KVxuICAgICAgZnVuY3Rpb24gZ2V0UmVxdWVzdEZyb21BcmdzIChhcmdzKSB7XG4gICAgICAgIGZvciAoY29uc3QgYXJnIG9mIGFyZ3MpIHtcbiAgICAgICAgICBpZiAoYXJnPy5yb3V0ZU9wdGlvbnMgJiYgYXJnLnVybCAmJiBhcmcubWV0aG9kKSB7XG4gICAgICAgICAgICByZXR1cm4gYXJnXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsXG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIGhhbmRsZXJXcmFwcGVyIChoYW5kbGVyLCBob29rTmFtZSwgc3BhbkF0dHJpYnV0ZXMgPSB7fSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gaGFuZGxlcldyYXBwZWQgKC4uLmFyZ3MpIHtcbiAgICAgICAgICAvKiogQHR5cGUge0Zhc3RpZnlPdGVsSW5zdHJ1bWVudGF0aW9ufSAqL1xuICAgICAgICAgIGNvbnN0IGluc3RydW1lbnRhdGlvbiA9IHRoaXNba0luc3RydW1lbnRhdGlvbl1cblxuICAgICAgICAgIGNvbnN0IHJlcXVlc3QgPSBnZXRSZXF1ZXN0RnJvbUFyZ3MoYXJncylcbiAgICAgICAgICBpZiAocmVxdWVzdCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgaW5zdHJ1bWVudGF0aW9uLmxvZ2dlci5kZWJ1ZyhcbiAgICAgICAgICAgICAgYElnbm9yaW5nIHJvdXRlIGluc3RydW1lbnRhdGlvbiBiZWNhdXNlICR7aG9va05hbWV9IHdhcyBjYWxsZWQgd2l0aG91dCBhIEZhc3RpZnkgcmVxdWVzdCBhcmd1bWVudGBcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIHJldHVybiBoYW5kbGVyLmNhbGwodGhpcywgLi4uYXJncylcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoaW5zdHJ1bWVudGF0aW9uLmlzRW5hYmxlZCgpID09PSBmYWxzZSB8fCByZXF1ZXN0LnJvdXRlT3B0aW9ucy5jb25maWc/Lm90ZWwgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICBpbnN0cnVtZW50YXRpb24ubG9nZ2VyLmRlYnVnKFxuICAgICAgICAgICAgICBgSWdub3Jpbmcgcm91dGUgaW5zdHJ1bWVudGF0aW9uICR7cmVxdWVzdC5yb3V0ZU9wdGlvbnMubWV0aG9kfSAke3JlcXVlc3Qucm91dGVPcHRpb25zLnVybH0gYmVjYXVzZSBpdCBpcyBkaXNhYmxlZGBcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIHJldHVybiBoYW5kbGVyLmNhbGwodGhpcywgLi4uYXJncylcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoaW5zdHJ1bWVudGF0aW9uW2tJZ25vcmVQYXRoc10/Lih7XG4gICAgICAgICAgICB1cmw6IHJlcXVlc3QudXJsLFxuICAgICAgICAgICAgbWV0aG9kOiByZXF1ZXN0Lm1ldGhvZCxcbiAgICAgICAgICB9KSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgaW5zdHJ1bWVudGF0aW9uLmxvZ2dlci5kZWJ1ZyhcbiAgICAgICAgICAgICAgYElnbm9yaW5nIHJvdXRlIGluc3RydW1lbnRhdGlvbiAke3JlcXVlc3Qucm91dGVPcHRpb25zLm1ldGhvZH0gJHtyZXF1ZXN0LnJvdXRlT3B0aW9ucy51cmx9IGJlY2F1c2UgaXQgbWF0Y2hlcyB0aGUgaWdub3JlIHBhdGhgXG4gICAgICAgICAgICApXG4gICAgICAgICAgICByZXR1cm4gaGFuZGxlci5jYWxsKHRoaXMsIC4uLmFyZ3MpXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLyogYzggaWdub3JlIG5leHQgKi9cbiAgICAgICAgICBjb25zdCBjdHggPSByZXF1ZXN0W2tSZXF1ZXN0Q29udGV4dF0gPz8gY29udGV4dC5hY3RpdmUoKVxuICAgICAgICAgIGNvbnN0IGhhbmRsZXJOYW1lID0gaGFuZGxlci5uYW1lPy5sZW5ndGggPiAwXG4gICAgICAgICAgICA/IGhhbmRsZXIubmFtZVxuICAgICAgICAgICAgOiB0aGlzLnBsdWdpbk5hbWUgLyogYzggaWdub3JlIG5leHQgKi8gPz8gQU5PTllNT1VTX0ZVTkNUSU9OX05BTUUgLyogYzggaWdub3JlIG5leHQgKi9cblxuICAgICAgICAgIGNvbnN0IHNwYW4gPSBpbnN0cnVtZW50YXRpb24udHJhY2VyLnN0YXJ0U3BhbihcbiAgICAgICAgICAgIGAke2hvb2tOYW1lfSAtICR7aGFuZGxlck5hbWV9YCxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgYXR0cmlidXRlczogc3BhbkF0dHJpYnV0ZXNcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjdHhcbiAgICAgICAgICApXG5cbiAgICAgICAgICBpZiAoaW5zdHJ1bWVudGF0aW9uLl9saWZlY3ljbGVIb29rICE9IG51bGwpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGluc3RydW1lbnRhdGlvbi5fbGlmZWN5Y2xlSG9vayhzcGFuLCB7XG4gICAgICAgICAgICAgICAgaG9va05hbWUsXG4gICAgICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgICAgICBoYW5kbGVyOiBoYW5kbGVyTmFtZVxuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgIGluc3RydW1lbnRhdGlvbi5sb2dnZXIuZXJyb3IoeyBlcnIgfSwgJ0V4ZWN1dGlvbiBvZiBsaWZlY3ljbGVIb29rIGZhaWxlZCcpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIGNvbnRleHQud2l0aChcbiAgICAgICAgICAgIHRyYWNlLnNldFNwYW4oY3R4LCBzcGFuKSxcbiAgICAgICAgICAgIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25zdCByZXMgPSBoYW5kbGVyLmNhbGwodGhpcywgLi4uYXJncylcblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgcmVzPy50aGVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gcmVzLnRoZW4oXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgc3Bhbi5lbmQoKVxuICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHRcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgIHNwYW4uc2V0U3RhdHVzKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFNwYW5TdGF0dXNDb2RlLkVSUk9SLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogZXJyb3IubWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgaWYgKGluc3RydW1lbnRhdGlvbltrUmVjb3JkRXhjZXB0aW9uc10gIT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzcGFuLnJlY29yZEV4Y2VwdGlvbihlcnJvcilcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgc3Bhbi5lbmQoKVxuICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlcnJvcilcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHNwYW4uZW5kKClcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzXG4gICAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgc3Bhbi5zZXRTdGF0dXMoe1xuICAgICAgICAgICAgICAgICAgY29kZTogU3BhblN0YXR1c0NvZGUuRVJST1IsXG4gICAgICAgICAgICAgICAgICBtZXNzYWdlOiBlcnJvci5tZXNzYWdlXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICBpZiAoaW5zdHJ1bWVudGF0aW9uW2tSZWNvcmRFeGNlcHRpb25zXSAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICAgIHNwYW4ucmVjb3JkRXhjZXB0aW9uKGVycm9yKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBzcGFuLmVuZCgpXG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyb3JcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRoaXNcbiAgICAgICAgICApXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBGYXN0aWZ5T3RlbEluc3RydW1lbnRhdGlvblxubW9kdWxlLmV4cG9ydHMuRmFzdGlmeU90ZWxJbnN0cnVtZW50YXRpb24gPSBGYXN0aWZ5T3RlbEluc3RydW1lbnRhdGlvblxuIl0sIm5hbWVzIjpbXSwiaWdub3JlTGlzdCI6WzBdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///(rsc)/./node_modules/.pnpm/@fastify+otel@0.18.0_@opentelemetry+api@1.9.1/node_modules/@fastify/otel/index.js\n");
/***/ }),
/***/ "(rsc)/./node_modules/.pnpm/@fastify+otel@0.18.0_@opentelemetry+api@1.9.1/node_modules/@fastify/otel/package.json":
/*!******************************************************************************************************************!*\
!*** ./node_modules/.pnpm/@fastify+otel@0.18.0_@opentelemetry+api@1.9.1/node_modules/@fastify/otel/package.json ***!
\******************************************************************************************************************/
/***/ ((module) => {
module.exports = /*#__PURE__*/JSON.parse('{"name":"@fastify/otel","version":"0.18.0","description":"Official Fastify OpenTelemetry Instrumentation","main":"index.js","type":"commonjs","types":"types/index.d.ts","scripts":{"lint":"eslint","lint:fix":"eslint --fix","test":"npm run test:all && npm run test:typescript","test:unit":"c8 --100 node --test","test:all":"npm run test:v4 && npm run test:v5","test:v4":"cross-env FASTIFY_VERSION=fastifyv4 npm run test:unit","test:v5":"cross-env FASTIFY_VERSION=fastify npm run test:unit","test:coverage":"c8 node --test && c8 report --reporter=html","test:typescript":"tsd"},"repository":{"type":"git","url":"git+https://github.com/fastify/otel.git"},"keywords":["plugin","helper","fastify","instrumentation","otel","opentelemetry"],"author":"Carlos Fuentes - @metcoder95 (https://metcoder.dev)","license":"MIT","bugs":{"url":"https://github.com/fastify/otel/issues"},"homepage":"https://github.com/fastify/otel#readme","funding":[{"type":"github","url":"https://github.com/sponsors/fastify"},{"type":"opencollective","url":"https://opencollective.com/fastify"}],"devDependencies":{"@fastify/type-provider-typebox":"^6.1.0","@opentelemetry/context-async-hooks":"^2.0.0","@opentelemetry/contrib-test-utils":"^0.59.0","@opentelemetry/instrumentation-http":"^0.212.0","@opentelemetry/propagator-jaeger":"^2.0.0","@opentelemetry/sdk-trace-base":"^2.0.0","@opentelemetry/sdk-trace-node":"^2.2.0","@types/node":"^25.0.3","c8":"^11.0.0","cross-env":"^10.0.0","eslint":"^9.16.0","fastify":"^5.1.0","fastify-plugin":"^5.1.0","fastifyv4":"npm:fastify@^4.0.0","neostandard":"^0.12.0","tsd":"^0.33.0"},"dependencies":{"@opentelemetry/core":"^2.0.0","@opentelemetry/instrumentation":"^0.212.0","@opentelemetry/semantic-conventions":"^1.28.0","minimatch":"^10.2.4"},"peerDependencies":{"@opentelemetry/api":"^1.9.0"},"tsd":{"directory":"types"}}');
/***/ }),
/***/ "(ssr)/./node_modules/.pnpm/@fastify+otel@0.18.0_@opentelemetry+api@1.9.1/node_modules/@fastify/otel/index.js":
/*!**************************************************************************************************************!*\
!*** ./node_modules/.pnpm/@fastify+otel@0.18.0_@opentelemetry+api@1.9.1/node_modules/@fastify/otel/index.js ***!
\**************************************************************************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
eval("\nconst dc = __webpack_require__(/*! node:diagnostics_channel */ \"node:diagnostics_channel\")\nconst { context, trace, SpanStatusCode, propagation, diag } = __webpack_require__(/*! @opentelemetry/api */ \"(ssr)/./node_modules/.pnpm/@opentelemetry+api@1.9.1/node_modules/@opentelemetry/api/build/esm/index.js\")\nconst { getRPCMetadata, RPCType } = __webpack_require__(/*! @opentelemetry/core */ \"(ssr)/./node_modules/.pnpm/@opentelemetry+core@2.6.1_@opentelemetry+api@1.9.1/node_modules/@opentelemetry/core/build/esm/index.js\")\nconst {\n ATTR_HTTP_ROUTE,\n ATTR_HTTP_RESPONSE_STATUS_CODE,\n ATTR_HTTP_REQUEST_METHOD,\n ATTR_URL_PATH\n} = __webpack_require__(/*! @opentelemetry/semantic-conventions */ \"(ssr)/./node_modules/.pnpm/@opentelemetry+semantic-conventions@1.40.0/node_modules/@opentelemetry/semantic-conventions/build/esm/index.js\")\nconst { InstrumentationBase } = __webpack_require__(/*! @opentelemetry/instrumentation */ \"(ssr)/./node_modules/.pnpm/@opentelemetry+instrumentation@0.212.0_@opentelemetry+api@1.9.1/node_modules/@opentelemetry/instrumentation/build/esm/index.js\")\n\nconst {\n version: PACKAGE_VERSION,\n name: PACKAGE_NAME\n} = __webpack_require__(/*! ./package.json */ \"(ssr)/./node_modules/.pnpm/@fastify+otel@0.18.0_@opentelemetry+api@1.9.1/node_modules/@fastify/otel/package.json\")\n\n// Constants\nconst SUPPORTED_VERSIONS = '>=4.0.0 <6'\nconst FASTIFY_HOOKS = [\n 'onRequest',\n 'preParsing',\n 'preValidation',\n 'preHandler',\n 'preSerialization',\n 'onSend',\n 'onResponse',\n 'onError'\n]\nconst ATTRIBUTE_NAMES = {\n HOOK_NAME: 'hook.name',\n FASTIFY_TYPE: 'fastify.type',\n HOOK_CALLBACK_NAME: 'hook.callback.name',\n ROOT: 'fastify.root'\n}\nconst HOOK_TYPES = {\n ROUTE: 'route-hook',\n INSTANCE: 'hook',\n HANDLER: 'request-handler'\n}\nconst ANONYMOUS_FUNCTION_NAME = 'anonymous'\n\n// Symbols\nconst kInstrumentation = Symbol('fastify otel instance')\nconst kRequestSpan = Symbol('fastify otel request spans')\nconst kRequestContext = Symbol('fastify otel request context')\nconst kAddHookOriginal = Symbol('fastify otel addhook original')\nconst kSetNotFoundOriginal = Symbol('fastify otel setnotfound original')\nconst kIgnorePaths = Symbol('fastify otel ignore path')\nconst kRecordExceptions = Symbol('fastify otel record exceptions')\n\nclass FastifyOtelInstrumentation extends InstrumentationBase {\n logger = null\n _requestHook = null\n _lifecycleHook = null\n\n constructor (config) {\n super(PACKAGE_NAME, PACKAGE_VERSION, config)\n this.logger = diag.createComponentLogger({ namespace: PACKAGE_NAME })\n this[kIgnorePaths] = null\n this[kRecordExceptions] = true\n\n if (config?.recordExceptions != null) {\n if (typeof config.recordExceptions !== 'boolean') {\n throw new TypeError('recordExceptions must be a boolean')\n }\n\n this[kRecordExceptions] = config.recordExceptions\n }\n if (typeof config?.requestHook === 'function') {\n this._requestHook = config.requestHook\n }\n if (typeof config?.lifecycleHook === 'function') {\n this._lifecycleHook = config.lifecycleHook\n }\n\n if (config?.ignorePaths != null || process.env.OTEL_FASTIFY_IGNORE_PATHS != null) {\n const ignorePaths = config?.ignorePaths ?? process.env.OTEL_FASTIFY_IGNORE_PATHS\n\n if ((typeof ignorePaths !== 'string' || ignorePaths.length === 0) && typeof ignorePaths !== 'function') {\n throw new TypeError(\n 'ignorePaths must be a string or a function'\n )\n }\n\n let globMatcher = null\n\n this[kIgnorePaths] = (routeOptions) => {\n if (typeof ignorePaths === 'function') {\n return ignorePaths(routeOptions)\n } else {\n // Using minimatch to match the path until path.matchesGlob is out of experimental\n // path.matchesGlob uses minimatch internally\n if (globMatcher == null) {\n globMatcher = (__webpack_require__(/*! minimatch */ \"(ssr)/./node_modules/.pnpm/minimatch@10.2.5/node_modules/minimatch/dist/commonjs/index.js\").minimatch)\n }\n\n return globMatcher(routeOptions.url, ignorePaths)\n }\n }\n }\n }\n\n enable () {\n if (this._handleInitialization === undefined && this.getConfig().registerOnInitialization) {\n this._handleInitialization = (message) => {\n // Cannot use `fastify.register(plugin)` because it is lazily executed and\n // thus requires user code to await fastify instance first.\n this.plugin()(message.fastify, undefined, () => {})\n\n // Add an empty plugin to keep `app.hasPlugin('@fastify/otel')` invariant\n const emptyPlugin = (_, __, done) => {\n done()\n }\n emptyPlugin[Symbol.for('skip-override')] = true\n emptyPlugin[Symbol.for('fastify.display-name')] = '@fastify/otel'\n message.fastify.register(emptyPlugin)\n }\n dc.subscribe('fastify.initialization', this._handleInitialization)\n }\n return super.enable()\n }\n\n disable () {\n if (this._handleInitialization) {\n dc.unsubscribe('fastify.initialization', this._handleInitialization)\n this._handleInitialization = undefined\n }\n return super.disable()\n }\n\n // We do not do patching in this instrumentation\n init () {\n return []\n }\n\n plugin () {\n const instrumentation = this\n\n FastifyInstrumentationPlugin[Symbol.for('skip-override')] = true\n FastifyInstrumentationPlugin[Symbol.for('fastify.display-name')] = '@fastify/otel'\n FastifyInstrumentationPlugin[Symbol.for('plugin-meta')] = {\n fastify: SUPPORTED_VERSIONS,\n name: '@fastify/otel',\n }\n\n return FastifyInstrumentationPlugin\n\n function FastifyInstrumentationPlugin (instance, opts, done) {\n instance.decorate(kInstrumentation, instrumentation)\n // addHook and notfoundHandler are essentially inherited from the prototype\n // what is important is to bound it to the right instance\n instance.decorate(kAddHookOriginal, instance.addHook)\n instance.decorate(kSetNotFoundOriginal, instance.setNotFoundHandler)\n instance.decorateRequest('opentelemetry', function openetelemetry () {\n const ctx = this[kRequestContext]\n const span = this[kRequestSpan]\n\n return {\n enabled: this.routeOptions.config?.otel !== false,\n span,\n tracer: instrumentation.tracer,\n context: ctx,\n inject: (carrier, setter) => {\n return propagation.inject(ctx, carrier, setter)\n },\n extract: (carrier, getter) => {\n return propagation.extract(ctx, carrier, getter)\n }\n }\n })\n instance.decorateRequest(kRequestSpan, null)\n instance.decorateRequest(kRequestContext, null)\n\n instance.addHook('onRoute', function otelWireRoute (routeOptions) {\n if (instrumentation[kIgnorePaths]?.(routeOptions) === true) {\n instrumentation.logger.debug(\n `Ignoring route instrumentation ${routeOptions.method} ${routeOptions.url} because it matches the ignore path`\n )\n return\n }\n\n if (routeOptions.config?.otel === false) {\n instrumentation.logger.debug(\n `Ignoring route instrumentation ${routeOptions.method} ${routeOptions.url} because it is disabled`\n )\n\n return\n }\n\n for (const hook of FASTIFY_HOOKS) {\n if (routeOptions[hook] != null) {\n const handlerLike = routeOptions[hook]\n\n if (typeof handlerLike === 'function') {\n routeOptions[hook] = handlerWrapper(handlerLike, hook, {\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - route -> ${hook}`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.ROUTE,\n [ATTR_HTTP_ROUTE]: routeOptions.url,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n handlerLike.name?.length > 0\n ? handlerLike.name\n : ANONYMOUS_FUNCTION_NAME /* c8 ignore next */\n })\n } else if (Array.isArray(handlerLike)) {\n const wrappedHandlers = []\n\n for (const handler of handlerLike) {\n wrappedHandlers.push(\n handlerWrapper(handler, hook, {\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - route -> ${hook}`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.ROUTE,\n [ATTR_HTTP_ROUTE]: routeOptions.url,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n handler.name?.length > 0\n ? handler.name\n : ANONYMOUS_FUNCTION_NAME\n })\n )\n }\n\n routeOptions[hook] = wrappedHandlers\n }\n }\n }\n\n // We always want to add the onSend hook to the route to be executed last\n if (routeOptions.onSend != null) {\n routeOptions.onSend = Array.isArray(routeOptions.onSend)\n ? [...routeOptions.onSend, finalizeResponseSpanHook]\n : [routeOptions.onSend, finalizeResponseSpanHook]\n } else {\n routeOptions.onSend = finalizeResponseSpanHook\n }\n\n // We always want to add the onError hook to the route to be executed last\n if (routeOptions.onError != null) {\n routeOptions.onError = Array.isArray(routeOptions.onError)\n ? [...routeOptions.onError, recordErrorInSpanHook]\n : [routeOptions.onError, recordErrorInSpanHook]\n } else {\n routeOptions.onError = recordErrorInSpanHook\n }\n\n routeOptions.handler = handlerWrapper(routeOptions.handler, 'handler', {\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - route-handler`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.HANDLER,\n [ATTR_HTTP_ROUTE]: routeOptions.url,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n routeOptions.handler.name.length > 0\n ? routeOptions.handler.name\n : ANONYMOUS_FUNCTION_NAME\n })\n })\n\n instance.addHook('onRequest', function startRequestSpanHook (request, _reply, hookDone) {\n if (\n this[kInstrumentation].isEnabled() === false ||\n request.routeOptions.config?.otel === false\n ) {\n return hookDone()\n }\n\n if (this[kInstrumentation][kIgnorePaths]?.({\n url: request.url,\n method: request.method,\n }) === true) {\n this[kInstrumentation].logger.debug(\n `Ignoring request ${request.method} ${request.url} because it matches the ignore path`\n )\n return hookDone()\n }\n\n let ctx = context.active()\n\n if (trace.getSpan(ctx) == null) {\n ctx = propagation.extract(ctx, request.headers)\n }\n\n const rpcMetadata = getRPCMetadata(ctx)\n\n if (\n request.routeOptions.url != null &&\n rpcMetadata?.type === RPCType.HTTP\n ) {\n rpcMetadata.route = request.routeOptions.url\n }\n\n const attributes = {\n [ATTRIBUTE_NAMES.ROOT]: '@fastify/otel',\n [ATTR_HTTP_REQUEST_METHOD]: request.method,\n [ATTR_URL_PATH]: request.url\n }\n\n if (request.routeOptions.url != null) {\n attributes[ATTR_HTTP_ROUTE] = request.routeOptions.url\n }\n\n /** @type {import('@opentelemetry/api').Span} */\n const span = this[kInstrumentation].tracer.startSpan('request', {\n attributes\n }, ctx)\n\n try {\n this[kInstrumentation]._requestHook?.(span, request)\n } catch (err) {\n this[kInstrumentation].logger.error({ err }, 'requestHook threw')\n }\n\n request[kRequestContext] = trace.setSpan(ctx, span)\n request[kRequestSpan] = span\n\n context.with(request[kRequestContext], () => {\n hookDone()\n })\n })\n\n // onResponse is the last hook to be executed, only added for 404 handlers\n instance.addHook('onResponse', function finalizeNotFoundSpanHook (request, reply, hookDone) {\n const span = request[kRequestSpan]\n\n if (span != null) {\n span.setAttributes({\n [ATTR_HTTP_RESPONSE_STATUS_CODE]: reply.statusCode\n })\n span.end()\n }\n\n request[kRequestSpan] = null\n\n hookDone()\n })\n\n instance.addHook = addHookPatched\n instance.setNotFoundHandler = setNotFoundHandlerPatched\n\n done()\n\n function finalizeResponseSpanHook (request, reply, payload, hookDone) {\n /** @type {import('@opentelemetry/api').Span} */\n const span = request[kRequestSpan]\n\n if (span != null) {\n if (reply.statusCode >= 500) {\n span.setStatus({ code: SpanStatusCode.ERROR })\n }\n\n span.setAttributes({\n [ATTR_HTTP_RESPONSE_STATUS_CODE]: reply.statusCode\n })\n span.end()\n }\n\n request[kRequestSpan] = null\n\n hookDone(null, payload)\n }\n\n function recordErrorInSpanHook (request, reply, error, hookDone) {\n /** @type {Span} */\n const span = request[kRequestSpan]\n\n if (span != null) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error.message\n })\n if (instrumentation[kRecordExceptions] !== false) {\n span.recordException(error)\n }\n }\n\n hookDone()\n }\n\n function addHookPatched (name, hook) {\n const addHookOriginal = this[kAddHookOriginal]\n\n if (FASTIFY_HOOKS.includes(name)) {\n return addHookOriginal.call(\n this,\n name,\n handlerWrapper(hook, name, {\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - ${name}`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.INSTANCE,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n hook.name?.length > 0\n ? hook.name\n : ANONYMOUS_FUNCTION_NAME /* c8 ignore next */\n })\n )\n } else {\n return addHookOriginal.call(this, name, hook)\n }\n }\n\n function setNotFoundHandlerPatched (hooks, handler) {\n const setNotFoundHandlerOriginal = this[kSetNotFoundOriginal]\n if (typeof hooks === 'function') {\n handler = handlerWrapper(hooks, 'notFoundHandler', {\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - not-found-handler`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.INSTANCE,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n hooks.name?.length > 0\n ? hooks.name\n : ANONYMOUS_FUNCTION_NAME /* c8 ignore next */\n })\n setNotFoundHandlerOriginal.call(this, handler)\n } else {\n if (hooks.preValidation != null) {\n hooks.preValidation = handlerWrapper(hooks.preValidation, 'notFoundHandler - preValidation', {\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - not-found-handler - preValidation`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.INSTANCE,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n hooks.preValidation.name?.length > 0\n ? hooks.preValidation.name\n : ANONYMOUS_FUNCTION_NAME /* c8 ignore next */\n })\n }\n\n if (hooks.preHandler != null) {\n hooks.preHandler = handlerWrapper(hooks.preHandler, 'notFoundHandler - preHandler', {\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - not-found-handler - preHandler`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.INSTANCE,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n hooks.preHandler.name?.length > 0\n ? hooks.preHandler.name\n : ANONYMOUS_FUNCTION_NAME /* c8 ignore next */\n })\n }\n\n handler = handlerWrapper(handler, 'notFoundHandler', {\n [ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - not-found-handler`,\n [ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.INSTANCE,\n [ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:\n handler.name?.length > 0\n ? handler.name\n : ANONYMOUS_FUNCTION_NAME /* c8 ignore next */\n })\n setNotFoundHandlerOriginal.call(this, hooks, handler)\n }\n }\n\n // regular handlers are (request, reply), @fastify/websocket handlers are (socket, request)\n function getRequestFromArgs (args) {\n for (const arg of args) {\n if (arg?.routeOptions && arg.url && arg.method) {\n return arg\n }\n }\n return null\n }\n\n function handlerWrapper (handler, hookName, spanAttributes = {}) {\n return function handlerWrapped (...args) {\n /** @type {FastifyOtelInstrumentation} */\n const instrumentation = this[kInstrumentation]\n\n const request = getRequestFromArgs(args)\n if (request === null) {\n instrumentation.logger.debug(\n `Ignoring route instrumentation because ${hookName} was called without a Fastify request argument`\n )\n return handler.call(this, ...args)\n }\n\n if (instrumentation.isEnabled() === false || request.routeOptions.config?.otel === false) {\n instrumentation.logger.debug(\n `Ignoring route instrumentation ${request.routeOptions.method} ${request.routeOptions.url} because it is disabled`\n )\n return handler.call(this, ...args)\n }\n\n if (instrumentation[kIgnorePaths]?.({\n url: request.url,\n method: request.method,\n }) === true) {\n instrumentation.logger.debug(\n `Ignoring route instrumentation ${request.routeOptions.method} ${request.routeOptions.url} because it matches the ignore path`\n )\n return handler.call(this, ...args)\n }\n\n /* c8 ignore next */\n const ctx = request[kRequestContext] ?? context.active()\n const handlerName = handler.name?.length > 0\n ? handler.name\n : this.pluginName /* c8 ignore next */ ?? ANONYMOUS_FUNCTION_NAME /* c8 ignore next */\n\n const span = instrumentation.tracer.startSpan(\n `${hookName} - ${handlerName}`,\n {\n attributes: spanAttributes\n },\n ctx\n )\n\n if (instrumentation._lifecycleHook != null) {\n try {\n instrumentation._lifecycleHook(span, {\n hookName,\n request,\n handler: handlerName\n })\n } catch (err) {\n instrumentation.logger.error({ err }, 'Execution of lifecycleHook failed')\n }\n }\n\n return context.with(\n trace.setSpan(ctx, span),\n function () {\n try {\n const res = handler.call(this, ...args)\n\n if (typeof res?.then === 'function') {\n return res.then(\n result => {\n span.end()\n return result\n },\n error => {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error.message\n })\n if (instrumentation[kRecordExceptions] !== false) {\n span.recordException(error)\n }\n span.end()\n return Promise.reject(error)\n }\n )\n }\n\n span.end()\n return res\n } catch (error) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error.message\n })\n if (instrumentation[kRecordExceptions] !== false) {\n span.recordException(error)\n }\n span.end()\n throw error\n }\n },\n this\n )\n }\n }\n }\n }\n}\n\nmodule.exports = FastifyOtelInstrumentation\nmodule.exports.FastifyOtelInstrumentation = FastifyOtelInstrumentation\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHNzcikvLi9ub2RlX21vZHVsZXMvLnBucG0vQGZhc3RpZnkrb3RlbEAwLjE4LjBfQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4xL25vZGVfbW9kdWxlcy9AZmFzdGlmeS9vdGVsL2luZGV4LmpzIiwibWFwcGluZ3MiOiJBQUFZO0FBQ1osV0FBVyxtQkFBTyxDQUFDLDBEQUEwQjtBQUM3QyxRQUFRLG9EQUFvRCxFQUFFLG1CQUFPLENBQUMsa0lBQW9CO0FBQzFGLFFBQVEsMEJBQTBCLEVBQUUsbUJBQU8sQ0FBQyw4SkFBcUI7QUFDakU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUUsRUFBRSxtQkFBTyxDQUFDLHNMQUFxQztBQUNqRCxRQUFRLHNCQUFzQixFQUFFLG1CQUFPLENBQUMsaU1BQWdDOztBQUV4RTtBQUNBO0FBQ0E7QUFDQSxFQUFFLEVBQUUsbUJBQU8sQ0FBQyx3SUFBZ0I7O0FBRTVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSwrQ0FBK0MseUJBQXlCO0FBQ3hFO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQiw2SUFBOEI7QUFDeEQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMERBQTBEOztBQUUxRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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LDRDQUE0QyxpQkFBaUI7QUFDN0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHFFQUFxRTtBQUNyRTtBQUNBLHFCQUFxQiw0QkFBNEI7QUFDakQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esd0RBQXdELFVBQVU7QUFDbEU7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxnREFBZ0QsNkJBQTZCLEVBQUUsMEJBQTBCO0FBQ3pHO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7QUFDQSxnREFBZ0QsNkJBQTZCLEVBQUUsMEJBQTBCO0FBQ3pHO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZUFBZSxVQUFVLElBQUksWUFBWTtBQUN6QztBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmLGNBQWM7QUFDZCw2Q0FBNkMsS0FBSztBQUNsRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QjtBQUN2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHlDQUF5QyIsInNvdXJjZXMiOlsiL1VzZXJzL21hcmNtaW50ZWwvUHJvamVjdHMvZS10aWIuY29tL25vZGVfbW9kdWxlcy8ucG5wbS9AZmFzdGlmeStvdGVsQDAuMTguMF9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjEvbm9kZV9tb2R1bGVzL0BmYXN0aWZ5L290ZWwvaW5kZXguanMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnXG5jb25zdCBkYyA9IHJlcXVpcmUoJ25vZGU6ZGlhZ25vc3RpY3NfY2hhbm5lbCcpXG5jb25zdCB7IGNvbnRleHQsIHRyYWNlLCBTcGFuU3RhdHVzQ29kZSwgcHJvcGFnYXRpb24sIGRpYWcgfSA9IHJlcXVpcmUoJ0BvcGVudGVsZW1ldHJ5L2FwaScpXG5jb25zdCB7IGdldFJQQ01ldGFkYXRhLCBSUENUeXBlIH0gPSByZXF1aXJlKCdAb3BlbnRlbGVtZXRyeS9jb3JlJylcbmNvbnN0IHtcbiAgQVRUUl9IVFRQX1JPVVRFLFxuICBBVFRSX0hUVFBfUkVTUE9OU0VfU1RBVFVTX0NPREUsXG4gIEFUVFJfSFRUUF9SRVFVRVNUX01FVEhPRCxcbiAgQVRUUl9VUkxfUEFUSFxufSA9IHJlcXVpcmUoJ0BvcGVudGVsZW1ldHJ5L3NlbWFudGljLWNvbnZlbnRpb25zJylcbmNvbnN0IHsgSW5zdHJ1bWVudGF0aW9uQmFzZSB9ID0gcmVxdWlyZSgnQG9wZW50ZWxlbWV0cnkvaW5zdHJ1bWVudGF0aW9uJylcblxuY29uc3Qge1xuICB2ZXJzaW9uOiBQQUNLQUdFX1ZFUlNJT04sXG4gIG5hbWU6IFBBQ0tBR0VfTkFNRVxufSA9IHJlcXVpcmUoJy4vcGFja2FnZS5qc29uJylcblxuLy8gQ29uc3RhbnRzXG5jb25zdCBTVVBQT1JURURfVkVSU0lPTlMgPSAnPj00LjAuMCA8NidcbmNvbnN0IEZBU1RJRllfSE9PS1MgPSBbXG4gICdvblJlcXVlc3QnLFxuICAncHJlUGFyc2luZycsXG4gICdwcmVWYWxpZGF0aW9uJyxcbiAgJ3ByZUhhbmRsZXInLFxuICAncHJlU2VyaWFsaXphdGlvbicsXG4gICdvblNlbmQnLFxuICAnb25SZXNwb25zZScsXG4gICdvbkVycm9yJ1xuXVxuY29uc3QgQVRUUklCVVRFX05BTUVTID0ge1xuICBIT09LX05BTUU6ICdob29rLm5hbWUnLFxuICBGQVNUSUZZX1RZUEU6ICdmYXN0aWZ5LnR5cGUnLFxuICBIT09LX0NBTExCQUNLX05BTUU6ICdob29rLmNhbGxiYWNrLm5hbWUnLFxuICBST09UOiAnZmFzdGlmeS5yb290J1xufVxuY29uc3QgSE9PS19UWVBFUyA9IHtcbiAgUk9VVEU6ICdyb3V0ZS1ob29rJyxcbiAgSU5TVEFOQ0U6ICdob29rJyxcbiAgSEFORExFUjogJ3JlcXVlc3QtaGFuZGxlcidcbn1cbmNvbnN0IEFOT05ZTU9VU19GVU5DVElPTl9OQU1FID0gJ2Fub255bW91cydcblxuLy8gU3ltYm9sc1xuY29uc3Qga0luc3RydW1lbnRhdGlvbiA9IFN5bWJvbCgnZmFzdGlmeSBvdGVsIGluc3RhbmNlJylcbmNvbnN0IGtSZXF1ZXN0U3BhbiA9IFN5bWJvbCgnZmFzdGlmeSBvdGVsIHJlcXVlc3Qgc3BhbnMnKVxuY29uc3Qga1JlcXVlc3RDb250ZXh0ID0gU3ltYm9sKCdmYXN0aWZ5IG90ZWwgcmVxdWVzdCBjb250ZXh0JylcbmNvbnN0IGtBZGRIb29rT3JpZ2luYWwgPSBTeW1ib2woJ2Zhc3RpZnkgb3RlbCBhZGRob29rIG9yaWdpbmFsJylcbmNvbnN0IGtTZXROb3RGb3VuZE9yaWdpbmFsID0gU3ltYm9sKCdmYXN0aWZ5IG90ZWwgc2V0bm90Zm91bmQgb3JpZ2luYWwnKVxuY29uc3Qga0lnbm9yZVBhdGhzID0gU3ltYm9sKCdmYXN0aWZ5IG90ZWwgaWdub3JlIHBhdGgnKVxuY29uc3Qga1JlY29yZEV4Y2VwdGlvbnMgPSBTeW1ib2woJ2Zhc3RpZnkgb3RlbCByZWNvcmQgZXhjZXB0aW9ucycpXG5cbmNsYXNzIEZhc3RpZnlPdGVsSW5zdHJ1bWVudGF0aW9uIGV4dGVuZHMgSW5zdHJ1bWVudGF0aW9uQmFzZSB7XG4gIGxvZ2dlciA9IG51bGxcbiAgX3JlcXVlc3RIb29rID0gbnVsbFxuICBfbGlmZWN5Y2xlSG9vayA9IG51bGxcblxuICBjb25zdHJ1Y3RvciAoY29uZmlnKSB7XG4gICAgc3VwZXIoUEFDS0FHRV9OQU1FLCBQQUNLQUdFX1ZFUlNJT04sIGNvbmZpZylcbiAgICB0aGlzLmxvZ2dlciA9IGRpYWcuY3JlYXRlQ29tcG9uZW50TG9nZ2VyKHsgbmFtZXNwYWNlOiBQQUNLQUdFX05BTUUgfSlcbiAgICB0aGlzW2tJZ25vcmVQYXRoc10gPSBudWxsXG4gICAgdGhpc1trUmVjb3JkRXhjZXB0aW9uc10gPSB0cnVlXG5cbiAgICBpZiAoY29uZmlnPy5yZWNvcmRFeGNlcHRpb25zICE9IG51bGwpIHtcbiAgICAgIGlmICh0eXBlb2YgY29uZmlnLnJlY29yZEV4Y2VwdGlvbnMgIT09ICdib29sZWFuJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdyZWNvcmRFeGNlcHRpb25zIG11c3QgYmUgYSBib29sZWFuJylcbiAgICAgIH1cblxuICAgICAgdGhpc1trUmVjb3JkRXhjZXB0aW9uc10gPSBjb25maWcucmVjb3JkRXhjZXB0aW9uc1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGNvbmZpZz8ucmVxdWVzdEhvb2sgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRoaXMuX3JlcXVlc3RIb29rID0gY29uZmlnLnJlcXVlc3RIb29rXG4gICAgfVxuICAgIGlmICh0eXBlb2YgY29uZmlnPy5saWZlY3ljbGVIb29rID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aGlzLl9saWZlY3ljbGVIb29rID0gY29uZmlnLmxpZmVjeWNsZUhvb2tcbiAgICB9XG5cbiAgICBpZiAoY29uZmlnPy5pZ25vcmVQYXRocyAhPSBudWxsIHx8IHByb2Nlc3MuZW52Lk9URUxfRkFTVElGWV9JR05PUkVfUEFUSFMgIT0gbnVsbCkge1xuICAgICAgY29uc3QgaWdub3JlUGF0aHMgPSBjb25maWc/Lmlnbm9yZVBhdGhzID8/IHByb2Nlc3MuZW52Lk9URUxfRkFTVElGWV9JR05PUkVfUEFUSFNcblxuICAgICAgaWYgKCh0eXBlb2YgaWdub3JlUGF0aHMgIT09ICdzdHJpbmcnIHx8IGlnbm9yZVBhdGhzLmxlbmd0aCA9PT0gMCkgJiYgdHlwZW9mIGlnbm9yZVBhdGhzICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgJ2lnbm9yZVBhdGhzIG11c3QgYmUgYSBzdHJpbmcgb3IgYSBmdW5jdGlvbidcbiAgICAgICAgKVxuICAgICAgfVxuXG4gICAgICBsZXQgZ2xvYk1hdGNoZXIgPSBudWxsXG5cbiAgICAgIHRoaXNba0lnbm9yZVBhdGhzXSA9IChyb3V0ZU9wdGlvbnMpID0+IHtcbiAgICAgICAgaWYgKHR5cGVvZiBpZ25vcmVQYXRocyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIHJldHVybiBpZ25vcmVQYXRocyhyb3V0ZU9wdGlvbnMpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gVXNpbmcgbWluaW1hdGNoIHRvIG1hdGNoIHRoZSBwYXRoIHVudGlsIHBhdGgubWF0Y2hlc0dsb2IgaXMgb3V0IG9mIGV4cGVyaW1lbnRhbFxuICAgICAgICAgIC8vIHBhdGgubWF0Y2hlc0dsb2IgdXNlcyBtaW5pbWF0Y2ggaW50ZXJuYWxseVxuICAgICAgICAgIGlmIChnbG9iTWF0Y2hlciA9PSBudWxsKSB7XG4gICAgICAgICAgICBnbG9iTWF0Y2hlciA9IHJlcXVpcmUoJ21pbmltYXRjaCcpLm1pbmltYXRjaFxuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBnbG9iTWF0Y2hlcihyb3V0ZU9wdGlvbnMudXJsLCBpZ25vcmVQYXRocylcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGVuYWJsZSAoKSB7XG4gICAgaWYgKHRoaXMuX2hhbmRsZUluaXRpYWxpemF0aW9uID09PSB1bmRlZmluZWQgJiYgdGhpcy5nZXRDb25maWcoKS5yZWdpc3Rlck9uSW5pdGlhbGl6YXRpb24pIHtcbiAgICAgIHRoaXMuX2hhbmRsZUluaXRpYWxpemF0aW9uID0gKG1lc3NhZ2UpID0+IHtcbiAgICAgICAgLy8gQ2Fubm90IHVzZSBgZmFzdGlmeS5yZWdpc3RlcihwbHVnaW4pYCBiZWNhdXNlIGl0IGlzIGxhemlseSBleGVjdXRlZCBhbmRcbiAgICAgICAgLy8gdGh1cyByZXF1aXJlcyB1c2VyIGNvZGUgdG8gYXdhaXQgZmFzdGlmeSBpbnN0YW5jZSBmaXJzdC5cbiAgICAgICAgdGhpcy5wbHVnaW4oKShtZXNzYWdlLmZhc3RpZnksIHVuZGVmaW5lZCwgKCkgPT4ge30pXG5cbiAgICAgICAgLy8gQWRkIGFuIGVtcHR5IHBsdWdpbiB0byBrZWVwIGBhcHAuaGFzUGx1Z2luKCdAZmFzdGlmeS9vdGVsJylgIGludmFyaWFudFxuICAgICAgICBjb25zdCBlbXB0eVBsdWdpbiA9IChfLCBfXywgZG9uZSkgPT4ge1xuICAgICAgICAgIGRvbmUoKVxuICAgICAgICB9XG4gICAgICAgIGVtcHR5UGx1Z2luW1N5bWJvbC5mb3IoJ3NraXAtb3ZlcnJpZGUnKV0gPSB0cnVlXG4gICAgICAgIGVtcHR5UGx1Z2luW1N5bWJvbC5mb3IoJ2Zhc3RpZnkuZGlzcGxheS1uYW1lJyldID0gJ0BmYXN0aWZ5L290ZWwnXG4gICAgICAgIG1lc3NhZ2UuZmFzdGlmeS5yZWdpc3RlcihlbXB0eVBsdWdpbilcbiAgICAgIH1cbiAgICAgIGRjLnN1YnNjcmliZSgnZmFzdGlmeS5pbml0aWFsaXphdGlvbicsIHRoaXMuX2hhbmRsZUluaXRpYWxpemF0aW9uKVxuICAgIH1cbiAgICByZXR1cm4gc3VwZXIuZW5hYmxlKClcbiAgfVxuXG4gIGRpc2FibGUgKCkge1xuICAgIGlmICh0aGlzLl9oYW5kbGVJbml0aWFsaXphdGlvbikge1xuICAgICAgZGMudW5zdWJzY3JpYmUoJ2Zhc3RpZnkuaW5pdGlhbGl6YXRpb24nLCB0aGlzLl9oYW5kbGVJbml0aWFsaXphdGlvbilcbiAgICAgIHRoaXMuX2hhbmRsZUluaXRpYWxpemF0aW9uID0gdW5kZWZpbmVkXG4gICAgfVxuICAgIHJldHVybiBzdXBlci5kaXNhYmxlKClcbiAgfVxuXG4gIC8vIFdlIGRvIG5vdCBkbyBwYXRjaGluZyBpbiB0aGlzIGluc3RydW1lbnRhdGlvblxuICBpbml0ICgpIHtcbiAgICByZXR1cm4gW11cbiAgfVxuXG4gIHBsdWdpbiAoKSB7XG4gICAgY29uc3QgaW5zdHJ1bWVudGF0aW9uID0gdGhpc1xuXG4gICAgRmFzdGlmeUluc3RydW1lbnRhdGlvblBsdWdpbltTeW1ib2wuZm9yKCdza2lwLW92ZXJyaWRlJyldID0gdHJ1ZVxuICAgIEZhc3RpZnlJbnN0cnVtZW50YXRpb25QbHVnaW5bU3ltYm9sLmZvcignZmFzdGlmeS5kaXNwbGF5LW5hbWUnKV0gPSAnQGZhc3RpZnkvb3RlbCdcbiAgICBGYXN0aWZ5SW5zdHJ1bWVudGF0aW9uUGx1Z2luW1N5bWJvbC5mb3IoJ3BsdWdpbi1tZXRhJyldID0ge1xuICAgICAgZmFzdGlmeTogU1VQUE9SVEVEX1ZFUlNJT05TLFxuICAgICAgbmFtZTogJ0BmYXN0aWZ5L290ZWwnLFxuICAgIH1cblxuICAgIHJldHVybiBGYXN0aWZ5SW5zdHJ1bWVudGF0aW9uUGx1Z2luXG5cbiAgICBmdW5jdGlvbiBGYXN0aWZ5SW5zdHJ1bWVudGF0aW9uUGx1Z2luIChpbnN0YW5jZSwgb3B0cywgZG9uZSkge1xuICAgICAgaW5zdGFuY2UuZGVjb3JhdGUoa0luc3RydW1lbnRhdGlvbiwgaW5zdHJ1bWVudGF0aW9uKVxuICAgICAgLy8gYWRkSG9vayBhbmQgbm90Zm91bmRIYW5kbGVyIGFyZSBlc3NlbnRpYWxseSBpbmhlcml0ZWQgZnJvbSB0aGUgcHJvdG90eXBlXG4gICAgICAvLyB3aGF0IGlzIGltcG9ydGFudCBpcyB0byBib3VuZCBpdCB0byB0aGUgcmlnaHQgaW5zdGFuY2VcbiAgICAgIGluc3RhbmNlLmRlY29yYXRlKGtBZGRIb29rT3JpZ2luYWwsIGluc3RhbmNlLmFkZEhvb2spXG4gICAgICBpbnN0YW5jZS5kZWNvcmF0ZShrU2V0Tm90Rm91bmRPcmlnaW5hbCwgaW5zdGFuY2Uuc2V0Tm90Rm91bmRIYW5kbGVyKVxuICAgICAgaW5zdGFuY2UuZGVjb3JhdGVSZXF1ZXN0KCdvcGVudGVsZW1ldHJ5JywgZnVuY3Rpb24gb3BlbmV0ZWxlbWV0cnkgKCkge1xuICAgICAgICBjb25zdCBjdHggPSB0aGlzW2tSZXF1ZXN0Q29udGV4dF1cbiAgICAgICAgY29uc3Qgc3BhbiA9IHRoaXNba1JlcXVlc3RTcGFuXVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgZW5hYmxlZDogdGhpcy5yb3V0ZU9wdGlvbnMuY29uZmlnPy5vdGVsICE9PSBmYWxzZSxcbiAgICAgICAgICBzcGFuLFxuICAgICAgICAgIHRyYWNlcjogaW5zdHJ1bWVudGF0aW9uLnRyYWNlcixcbiAgICAgICAgICBjb250ZXh0OiBjdHgsXG4gICAgICAgICAgaW5qZWN0OiAoY2Fycmllciwgc2V0dGVyKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gcHJvcGFnYXRpb24uaW5qZWN0KGN0eCwgY2Fycmllciwgc2V0dGVyKVxuICAgICAgICAgIH0sXG4gICAgICAgICAgZXh0cmFjdDogKGNhcnJpZXIsIGdldHRlcikgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHByb3BhZ2F0aW9uLmV4dHJhY3QoY3R4LCBjYXJyaWVyLCBnZXR0ZXIpXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgaW5zdGFuY2UuZGVjb3JhdGVSZXF1ZXN0KGtSZXF1ZXN0U3BhbiwgbnVsbClcbiAgICAgIGluc3RhbmNlLmRlY29yYXRlUmVxdWVzdChrUmVxdWVzdENvbnRleHQsIG51bGwpXG5cbiAgICAgIGluc3RhbmNlLmFkZEhvb2soJ29uUm91dGUnLCBmdW5jdGlvbiBvdGVsV2lyZVJvdXRlIChyb3V0ZU9wdGlvbnMpIHtcbiAgICAgICAgaWYgKGluc3RydW1lbnRhdGlvbltrSWdub3JlUGF0aHNdPy4ocm91dGVPcHRpb25zKSA9PT0gdHJ1ZSkge1xuICAgICAgICAgIGluc3RydW1lbnRhdGlvbi5sb2dnZXIuZGVidWcoXG4gICAgICAgICAgICBgSWdub3Jpbmcgcm91dGUgaW5zdHJ1bWVudGF0aW9uICR7cm91dGVPcHRpb25zLm1ldGhvZH0gJHtyb3V0ZU9wdGlvbnMudXJsfSBiZWNhdXNlIGl0IG1hdGNoZXMgdGhlIGlnbm9yZSBwYXRoYFxuICAgICAgICAgIClcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChyb3V0ZU9wdGlvbnMuY29uZmlnPy5vdGVsID09PSBmYWxzZSkge1xuICAgICAgICAgIGluc3RydW1lbnRhdGlvbi5sb2dnZXIuZGVidWcoXG4gICAgICAgICAgICBgSWdub3Jpbmcgcm91dGUgaW5zdHJ1bWVudGF0aW9uICR7cm91dGVPcHRpb25zLm1ldGhvZH0gJHtyb3V0ZU9wdGlvbnMudXJsfSBiZWNhdXNlIGl0IGlzIGRpc2FibGVkYFxuICAgICAgICAgIClcblxuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChjb25zdCBob29rIG9mIEZBU1RJRllfSE9PS1MpIHtcbiAgICAgICAgICBpZiAocm91dGVPcHRpb25zW2hvb2tdICE9IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnN0IGhhbmRsZXJMaWtlID0gcm91dGVPcHRpb25zW2hvb2tdXG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgaGFuZGxlckxpa2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgcm91dGVPcHRpb25zW2hvb2tdID0gaGFuZGxlcldyYXBwZXIoaGFuZGxlckxpa2UsIGhvb2ssIHtcbiAgICAgICAgICAgICAgICBbQVRUUklCVVRFX05BTUVTLkhPT0tfTkFNRV06IGAke3RoaXMucGx1Z2luTmFtZX0gLSByb3V0ZSAtPiAke2hvb2t9YCxcbiAgICAgICAgICAgICAgICBbQVRUUklCVVRFX05BTUVTLkZBU1RJRllfVFlQRV06IEhPT0tfVFlQRVMuUk9VVEUsXG4gICAgICAgICAgICAgICAgW0FUVFJfSFRUUF9ST1VURV06IHJvdXRlT3B0aW9ucy51cmwsXG4gICAgICAgICAgICAgICAgW0FUVFJJQlVURV9OQU1FUy5IT09LX0NBTExCQUNLX05BTUVdOlxuICAgICAgICAgICAgICAgICAgaGFuZGxlckxpa2UubmFtZT8ubGVuZ3RoID4gMFxuICAgICAgICAgICAgICAgICAgICA/IGhhbmRsZXJMaWtlLm5hbWVcbiAgICAgICAgICAgICAgICAgICAgOiBBTk9OWU1PVVNfRlVOQ1RJT05fTkFNRSAvKiBjOCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KGhhbmRsZXJMaWtlKSkge1xuICAgICAgICAgICAgICBjb25zdCB3cmFwcGVkSGFuZGxlcnMgPSBbXVxuXG4gICAgICAgICAgICAgIGZvciAoY29uc3QgaGFuZGxlciBvZiBoYW5kbGVyTGlrZSkge1xuICAgICAgICAgICAgICAgIHdyYXBwZWRIYW5kbGVycy5wdXNoKFxuICAgICAgICAgICAgICAgICAgaGFuZGxlcldyYXBwZXIoaGFuZGxlciwgaG9vaywge1xuICAgICAgICAgICAgICAgICAgICBbQVRUUklCVVRFX05BTUVTLkhPT0tfTkFNRV06IGAke3RoaXMucGx1Z2luTmFtZX0gLSByb3V0ZSAtPiAke2hvb2t9YCxcbiAgICAgICAgICAgICAgICAgICAgW0FUVFJJQlVURV9OQU1FUy5GQVNUSUZZX1RZUEVdOiBIT09LX1RZUEVTLlJPVVRFLFxuICAgICAgICAgICAgICAgICAgICBbQVRUUl9IVFRQX1JPVVRFXTogcm91dGVPcHRpb25zLnVybCxcbiAgICAgICAgICAgICAgICAgICAgW0FUVFJJQlVURV9OQU1FUy5IT09LX0NBTExCQUNLX05BTUVdOlxuICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZXIubmFtZT8ubGVuZ3RoID4gMFxuICAgICAgICAgICAgICAgICAgICAgICAgPyBoYW5kbGVyLm5hbWVcbiAgICAgICAgICAgICAgICAgICAgICAgIDogQU5PTllNT1VTX0ZVTkNUSU9OX05BTUVcbiAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgcm91dGVPcHRpb25zW2hvb2tdID0gd3JhcHBlZEhhbmRsZXJzXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gV2UgYWx3YXlzIHdhbnQgdG8gYWRkIHRoZSBvblNlbmQgaG9vayB0byB0aGUgcm91dGUgdG8gYmUgZXhlY3V0ZWQgbGFzdFxuICAgICAgICBpZiAocm91dGVPcHRpb25zLm9uU2VuZCAhPSBudWxsKSB7XG4gICAgICAgICAgcm91dGVPcHRpb25zLm9uU2VuZCA9IEFycmF5LmlzQXJyYXkocm91dGVPcHRpb25zLm9uU2VuZClcbiAgICAgICAgICAgID8gWy4uLnJvdXRlT3B0aW9ucy5vblNlbmQsIGZpbmFsaXplUmVzcG9uc2VTcGFuSG9va11cbiAgICAgICAgICAgIDogW3JvdXRlT3B0aW9ucy5vblNlbmQsIGZpbmFsaXplUmVzcG9uc2VTcGFuSG9va11cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByb3V0ZU9wdGlvbnMub25TZW5kID0gZmluYWxpemVSZXNwb25zZVNwYW5Ib29rXG4gICAgICAgIH1cblxuICAgICAgICAvLyBXZSBhbHdheXMgd2FudCB0byBhZGQgdGhlIG9uRXJyb3IgaG9vayB0byB0aGUgcm91dGUgdG8gYmUgZXhlY3V0ZWQgbGFzdFxuICAgICAgICBpZiAocm91dGVPcHRpb25zLm9uRXJyb3IgIT0gbnVsbCkge1xuICAgICAgICAgIHJvdXRlT3B0aW9ucy5vbkVycm9yID0gQXJyYXkuaXNBcnJheShyb3V0ZU9wdGlvbnMub25FcnJvcilcbiAgICAgICAgICAgID8gWy4uLnJvdXRlT3B0aW9ucy5vbkVycm9yLCByZWNvcmRFcnJvckluU3Bhbkhvb2tdXG4gICAgICAgICAgICA6IFtyb3V0ZU9wdGlvbnMub25FcnJvciwgcmVjb3JkRXJyb3JJblNwYW5Ib29rXVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJvdXRlT3B0aW9ucy5vbkVycm9yID0gcmVjb3JkRXJyb3JJblNwYW5Ib29rXG4gICAgICAgIH1cblxuICAgICAgICByb3V0ZU9wdGlvbnMuaGFuZGxlciA9IGhhbmRsZXJXcmFwcGVyKHJvdXRlT3B0aW9ucy5oYW5kbGVyLCAnaGFuZGxlcicsIHtcbiAgICAgICAgICBbQVRUUklCVVRFX05BTUVTLkhPT0tfTkFNRV06IGAke3RoaXMucGx1Z2luTmFtZX0gLSByb3V0ZS1oYW5kbGVyYCxcbiAgICAgICAgICBbQVRUUklCVVRFX05BTUVTLkZBU1RJRllfVFlQRV06IEhPT0tfVFlQRVMuSEFORExFUixcbiAgICAgICAgICBbQVRUUl9IVFRQX1JPVVRFXTogcm91dGVPcHRpb25zLnVybCxcbiAgICAgICAgICBbQVRUUklCVVRFX05BTUVTLkhPT0tfQ0FMTEJBQ0tfTkFNRV06XG4gICAgICAgICAgICByb3V0ZU9wdGlvbnMuaGFuZGxlci5uYW1lLmxlbmd0aCA+IDBcbiAgICAgICAgICAgICAgPyByb3V0ZU9wdGlvbnMuaGFuZGxlci5uYW1lXG4gICAgICAgICAgICAgIDogQU5PTllNT1VTX0ZVTkNUSU9OX05BTUVcbiAgICAgICAgfSlcbiAgICAgIH0pXG5cbiAgICAgIGluc3RhbmNlLmFkZEhvb2soJ29uUmVxdWVzdCcsIGZ1bmN0aW9uIHN0YXJ0UmVxdWVzdFNwYW5Ib29rIChyZXF1ZXN0LCBfcmVwbHksIGhvb2tEb25lKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICB0aGlzW2tJbnN0cnVtZW50YXRpb25dLmlzRW5hYmxlZCgpID09PSBmYWxzZSB8fFxuICAgICAgICAgIHJlcXVlc3Qucm91dGVPcHRpb25zLmNvbmZpZz8ub3RlbCA9PT0gZmFsc2VcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuIGhvb2tEb25lKClcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzW2tJbnN0cnVtZW50YXRpb25dW2tJZ25vcmVQYXRoc10/Lih7XG4gICAgICAgICAgdXJsOiByZXF1ZXN0LnVybCxcbiAgICAgICAgICBtZXRob2Q6IHJlcXVlc3QubWV0aG9kLFxuICAgICAgICB9KSA9PT0gdHJ1ZSkge1xuICAgICAgICAgIHRoaXNba0luc3RydW1lbnRhdGlvbl0ubG9nZ2VyLmRlYnVnKFxuICAgICAgICAgICAgYElnbm9yaW5nIHJlcXVlc3QgJHtyZXF1ZXN0Lm1ldGhvZH0gJHtyZXF1ZXN0LnVybH0gYmVjYXVzZSBpdCBtYXRjaGVzIHRoZSBpZ25vcmUgcGF0aGBcbiAgICAgICAgICApXG4gICAgICAgICAgcmV0dXJuIGhvb2tEb25lKClcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBjdHggPSBjb250ZXh0LmFjdGl2ZSgpXG5cbiAgICAgICAgaWYgKHRyYWNlLmdldFNwYW4oY3R4KSA9PSBudWxsKSB7XG4gICAgICAgICAgY3R4ID0gcHJvcGFnYXRpb24uZXh0cmFjdChjdHgsIHJlcXVlc3QuaGVhZGVycylcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJwY01ldGFkYXRhID0gZ2V0UlBDTWV0YWRhdGEoY3R4KVxuXG4gICAgICAgIGlmIChcbiAgICAgICAgICByZXF1ZXN0LnJvdXRlT3B0aW9ucy51cmwgIT0gbnVsbCAmJlxuICAgICAgICAgIHJwY01ldGFkYXRhPy50eXBlID09PSBSUENUeXBlLkhUVFBcbiAgICAgICAgKSB7XG4gICAgICAgICAgcnBjTWV0YWRhdGEucm91dGUgPSByZXF1ZXN0LnJvdXRlT3B0aW9ucy51cmxcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGF0dHJpYnV0ZXMgPSB7XG4gICAgICAgICAgW0FUVFJJQlVURV9OQU1FUy5ST09UXTogJ0BmYXN0aWZ5L290ZWwnLFxuICAgICAgICAgIFtBVFRSX0hUVFBfUkVRVUVTVF9NRVRIT0RdOiByZXF1ZXN0Lm1ldGhvZCxcbiAgICAgICAgICBbQVRUUl9VUkxfUEFUSF06IHJlcXVlc3QudXJsXG4gICAgICAgIH1cblxuICAgICAgICBpZiAocmVxdWVzdC5yb3V0ZU9wdGlvbnMudXJsICE9IG51bGwpIHtcbiAgICAgICAgICBhdHRyaWJ1dGVzW0FUVFJfSFRUUF9ST1VURV0gPSByZXF1ZXN0LnJvdXRlT3B0aW9ucy51cmxcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KCdAb3BlbnRlbGVtZXRyeS9hcGknKS5TcGFufSAqL1xuICAgICAgICBjb25zdCBzcGFuID0gdGhpc1trSW5zdHJ1bWVudGF0aW9uXS50cmFjZXIuc3RhcnRTcGFuKCdyZXF1ZXN0Jywge1xuICAgICAgICAgIGF0dHJpYnV0ZXNcbiAgICAgICAgfSwgY3R4KVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdGhpc1trSW5zdHJ1bWVudGF0aW9uXS5fcmVxdWVzdEhvb2s/LihzcGFuLCByZXF1ZXN0KVxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICB0aGlzW2tJbnN0cnVtZW50YXRpb25dLmxvZ2dlci5lcnJvcih7IGVyciB9LCAncmVxdWVzdEhvb2sgdGhyZXcnKVxuICAgICAgICB9XG5cbiAgICAgICAgcmVxdWVzdFtrUmVxdWVzdENvbnRleHRdID0gdHJhY2Uuc2V0U3BhbihjdHgsIHNwYW4pXG4gICAgICAgIHJlcXVlc3Rba1JlcXVlc3RTcGFuXSA9IHNwYW5cblxuICAgICAgICBjb250ZXh0LndpdGgocmVxdWVzdFtrUmVxdWVzdENvbnRleHRdLCAoKSA9PiB7XG4gICAgICAgICAgaG9va0RvbmUoKVxuICAgICAgICB9KVxuICAgICAgfSlcblxuICAgICAgLy8gb25SZXNwb25zZSBpcyB0aGUgbGFzdCBob29rIHRvIGJlIGV4ZWN1dGVkLCBvbmx5IGFkZGVkIGZvciA0MDQgaGFuZGxlcnNcbiAgICAgIGluc3RhbmNlLmFkZEhvb2soJ29uUmVzcG9uc2UnLCBmdW5jdGlvbiBmaW5hbGl6ZU5vdEZvdW5kU3Bhbkhvb2sgKHJlcXVlc3QsIHJlcGx5LCBob29rRG9uZSkge1xuICAgICAgICBjb25zdCBzcGFuID0gcmVxdWVzdFtrUmVxdWVzdFNwYW5dXG5cbiAgICAgICAgaWYgKHNwYW4gIT0gbnVsbCkge1xuICAgICAgICAgIHNwYW4uc2V0QXR0cmlidXRlcyh7XG4gICAgICAgICAgICBbQVRUUl9IVFRQX1JFU1BPTlNFX1NUQVRVU19DT0RFXTogcmVwbHkuc3RhdHVzQ29kZVxuICAgICAgICAgIH0pXG4gICAgICAgICAgc3Bhbi5lbmQoKVxuICAgICAgICB9XG5cbiAgICAgICAgcmVxdWVzdFtrUmVxdWVzdFNwYW5dID0gbnVsbFxuXG4gICAgICAgIGhvb2tEb25lKClcbiAgICAgIH0pXG5cbiAgICAgIGluc3RhbmNlLmFkZEhvb2sgPSBhZGRIb29rUGF0Y2hlZFxuICAgICAgaW5zdGFuY2Uuc2V0Tm90Rm91bmRIYW5kbGVyID0gc2V0Tm90Rm91bmRIYW5kbGVyUGF0Y2hlZFxuXG4gICAgICBkb25lKClcblxuICAgICAgZnVuY3Rpb24gZmluYWxpemVSZXNwb25zZVNwYW5Ib29rIChyZXF1ZXN0LCByZXBseSwgcGF5bG9hZCwgaG9va0RvbmUpIHtcbiAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoJ0BvcGVudGVsZW1ldHJ5L2FwaScpLlNwYW59ICovXG4gICAgICAgIGNvbnN0IHNwYW4gPSByZXF1ZXN0W2tSZXF1ZXN0U3Bhbl1cblxuICAgICAgICBpZiAoc3BhbiAhPSBudWxsKSB7XG4gICAgICAgICAgaWYgKHJlcGx5LnN0YXR1c0NvZGUgPj0gNTAwKSB7XG4gICAgICAgICAgICBzcGFuLnNldFN0YXR1cyh7IGNvZGU6IFNwYW5TdGF0dXNDb2RlLkVSUk9SIH0pXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGVzKHtcbiAgICAgICAgICAgIFtBVFRSX0hUVFBfUkVTUE9OU0VfU1RBVFVTX0NPREVdOiByZXBseS5zdGF0dXNDb2RlXG4gICAgICAgICAgfSlcbiAgICAgICAgICBzcGFuLmVuZCgpXG4gICAgICAgIH1cblxuICAgICAgICByZXF1ZXN0W2tSZXF1ZXN0U3Bhbl0gPSBudWxsXG5cbiAgICAgICAgaG9va0RvbmUobnVsbCwgcGF5bG9hZClcbiAgICAgIH1cblxuICAgICAgZnVuY3Rpb24gcmVjb3JkRXJyb3JJblNwYW5Ib29rIChyZXF1ZXN0LCByZXBseSwgZXJyb3IsIGhvb2tEb25lKSB7XG4gICAgICAgIC8qKiBAdHlwZSB7U3Bhbn0gKi9cbiAgICAgICAgY29uc3Qgc3BhbiA9IHJlcXVlc3Rba1JlcXVlc3RTcGFuXVxuXG4gICAgICAgIGlmIChzcGFuICE9IG51bGwpIHtcbiAgICAgICAgICBzcGFuLnNldFN0YXR1cyh7XG4gICAgICAgICAgICBjb2RlOiBTcGFuU3RhdHVzQ29kZS5FUlJPUixcbiAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2VcbiAgICAgICAgICB9KVxuICAgICAgICAgIGlmIChpbnN0cnVtZW50YXRpb25ba1JlY29yZEV4Y2VwdGlvbnNdICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgc3Bhbi5yZWNvcmRFeGNlcHRpb24oZXJyb3IpXG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaG9va0RvbmUoKVxuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiBhZGRIb29rUGF0Y2hlZCAobmFtZSwgaG9vaykge1xuICAgICAgICBjb25zdCBhZGRIb29rT3JpZ2luYWwgPSB0aGlzW2tBZGRIb29rT3JpZ2luYWxdXG5cbiAgICAgICAgaWYgKEZBU1RJRllfSE9PS1MuaW5jbHVkZXMobmFtZSkpIHtcbiAgICAgICAgICByZXR1cm4gYWRkSG9va09yaWdpbmFsLmNhbGwoXG4gICAgICAgICAgICB0aGlzLFxuICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgIGhhbmRsZXJXcmFwcGVyKGhvb2ssIG5hbWUsIHtcbiAgICAgICAgICAgICAgW0FUVFJJQlVURV9OQU1FUy5IT09LX05BTUVdOiBgJHt0aGlzLnBsdWdpbk5hbWV9IC0gJHtuYW1lfWAsXG4gICAgICAgICAgICAgIFtBVFRSSUJVVEVfTkFNRVMuRkFTVElGWV9UWVBFXTogSE9PS19UWVBFUy5JTlNUQU5DRSxcbiAgICAgICAgICAgICAgW0FUVFJJQlVURV9OQU1FUy5IT09LX0NBTExCQUNLX05BTUVdOlxuICAgICAgICAgICAgICAgIGhvb2submFtZT8ubGVuZ3RoID4gMFxuICAgICAgICAgICAgICAgICAgPyBob29rLm5hbWVcbiAgICAgICAgICAgICAgICAgIDogQU5PTllNT1VTX0ZVTkNUSU9OX05BTUUgLyogYzggaWdub3JlIG5leHQgKi9cbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBhZGRIb29rT3JpZ2luYWwuY2FsbCh0aGlzLCBuYW1lLCBob29rKVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIHNldE5vdEZvdW5kSGFuZGxlclBhdGNoZWQgKGhvb2tzLCBoYW5kbGVyKSB7XG4gICAgICAgIGNvbnN0IHNldE5vdEZvdW5kSGFuZGxlck9yaWdpbmFsID0gdGhpc1trU2V0Tm90Rm91bmRPcmlnaW5hbF1cbiAgICAgICAgaWYgKHR5cGVvZiBob29rcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIGhhbmRsZXIgPSBoYW5kbGVyV3JhcHBlcihob29rcywgJ25vdEZvdW5kSGFuZGxlcicsIHtcbiAgICAgICAgICAgIFtBVFRSSUJVVEVfTkFNRVMuSE9PS19OQU1FXTogYCR7dGhpcy5wbHVnaW5OYW1lfSAtIG5vdC1mb3VuZC1oYW5kbGVyYCxcbiAgICAgICAgICAgIFtBVFRSSUJVVEVfTkFNRVMuRkFTVElGWV9UWVBFXTogSE9PS19UWVBFUy5JTlNUQU5DRSxcbiAgICAgICAgICAgIFtBVFRSSUJVVEVfTkFNRVMuSE9PS19DQUxMQkFDS19OQU1FXTpcbiAgICAgICAgICAgICAgaG9va3MubmFtZT8ubGVuZ3RoID4gMFxuICAgICAgICAgICAgICAgID8gaG9va3MubmFtZVxuICAgICAgICAgICAgICAgIDogQU5PTllNT1VTX0ZVTkNUSU9OX05BTUUgLyogYzggaWdub3JlIG5leHQgKi9cbiAgICAgICAgICB9KVxuICAgICAgICAgIHNldE5vdEZvdW5kSGFuZGxlck9yaWdpbmFsLmNhbGwodGhpcywgaGFuZGxlcilcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoaG9va3MucHJlVmFsaWRhdGlvbiAhPSBudWxsKSB7XG4gICAgICAgICAgICBob29rcy5wcmVWYWxpZGF0aW9uID0gaGFuZGxlcldyYXBwZXIoaG9va3MucHJlVmFsaWRhdGlvbiwgJ25vdEZvdW5kSGFuZGxlciAtIHByZVZhbGlkYXRpb24nLCB7XG4gICAgICAgICAgICAgIFtBVFRSSUJVVEVfTkFNRVMuSE9PS19OQU1FXTogYCR7dGhpcy5wbHVnaW5OYW1lfSAtIG5vdC1mb3VuZC1oYW5kbGVyIC0gcHJlVmFsaWRhdGlvbmAsXG4gICAgICAgICAgICAgIFtBVFRSSUJVVEVfTkFNRVMuRkFTVElGWV9UWVBFXTogSE9PS19UWVBFUy5JTlNUQU5DRSxcbiAgICAgICAgICAgICAgW0FUVFJJQlVURV9OQU1FUy5IT09LX0NBTExCQUNLX05BTUVdOlxuICAgICAgICAgICAgICAgIGhvb2tzLnByZVZhbGlkYXRpb24ubmFtZT8ubGVuZ3RoID4gMFxuICAgICAgICAgICAgICAgICAgPyBob29rcy5wcmVWYWxpZGF0aW9uLm5hbWVcbiAgICAgICAgICAgICAgICAgIDogQU5PTllNT1VTX0ZVTkNUSU9OX05BTUUgLyogYzggaWdub3JlIG5leHQgKi9cbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGhvb2tzLnByZUhhbmRsZXIgIT0gbnVsbCkge1xuICAgICAgICAgICAgaG9va3MucHJlSGFuZGxlciA9IGhhbmRsZXJXcmFwcGVyKGhvb2tzLnByZUhhbmRsZXIsICdub3RGb3VuZEhhbmRsZXIgLSBwcmVIYW5kbGVyJywge1xuICAgICAgICAgICAgICBbQVRUUklCVVRFX05BTUVTLkhPT0tfTkFNRV06IGAke3RoaXMucGx1Z2luTmFtZX0gLSBub3QtZm91bmQtaGFuZGxlciAtIHByZUhhbmRsZXJgLFxuICAgICAgICAgICAgICBbQVRUUklCVVRFX05BTUVTLkZBU1RJRllfVFlQRV06IEhPT0tfVFlQRVMuSU5TVEFOQ0UsXG4gICAgICAgICAgICAgIFtBVFRSSUJVVEVfTkFNRVMuSE9PS19DQUxMQkFDS19OQU1FXTpcbiAgICAgICAgICAgICAgICBob29rcy5wcmVIYW5kbGVyLm5hbWU/Lmxlbmd0aCA+IDBcbiAgICAgICAgICAgICAgICAgID8gaG9va3MucHJlSGFuZGxlci5uYW1lXG4gICAgICAgICAgICAgICAgICA6IEFOT05ZTU9VU19GVU5DVElPTl9OQU1FIC8qIGM4IGlnbm9yZSBuZXh0ICovXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGhhbmRsZXIgPSBoYW5kbGVyV3JhcHBlcihoYW5kbGVyLCAnbm90Rm91bmRIYW5kbGVyJywge1xuICAgICAgICAgICAgW0FUVFJJQlVURV9OQU1FUy5IT09LX05BTUVdOiBgJHt0aGlzLnBsdWdpbk5hbWV9IC0gbm90LWZvdW5kLWhhbmRsZXJgLFxuICAgICAgICAgICAgW0FUVFJJQlVURV9OQU1FUy5GQVNUSUZZX1RZUEVdOiBIT09LX1RZUEVTLklOU1RBTkNFLFxuICAgICAgICAgICAgW0FUVFJJQlVURV9OQU1FUy5IT09LX0NBTExCQUNLX05BTUVdOlxuICAgICAgICAgICAgICBoYW5kbGVyLm5hbWU/Lmxlbmd0aCA+IDBcbiAgICAgICAgICAgICAgICA/IGhhbmRsZXIubmFtZVxuICAgICAgICAgICAgICAgIDogQU5PTllNT1VTX0ZVTkNUSU9OX05BTUUgLyogYzggaWdub3JlIG5leHQgKi9cbiAgICAgICAgICB9KVxuICAgICAgICAgIHNldE5vdEZvdW5kSGFuZGxlck9yaWdpbmFsLmNhbGwodGhpcywgaG9va3MsIGhhbmRsZXIpXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gcmVndWxhciBoYW5kbGVycyBhcmUgKHJlcXVlc3QsIHJlcGx5KSwgQGZhc3RpZnkvd2Vic29ja2V0IGhhbmRsZXJzIGFyZSAoc29ja2V0LCByZXF1ZXN0KVxuICAgICAgZnVuY3Rpb24gZ2V0UmVxdWVzdEZyb21BcmdzIChhcmdzKSB7XG4gICAgICAgIGZvciAoY29uc3QgYXJnIG9mIGFyZ3MpIHtcbiAgICAgICAgICBpZiAoYXJnPy5yb3V0ZU9wdGlvbnMgJiYgYXJnLnVybCAmJiBhcmcubWV0aG9kKSB7XG4gICAgICAgICAgICByZXR1cm4gYXJnXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsXG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIGhhbmRsZXJXcmFwcGVyIChoYW5kbGVyLCBob29rTmFtZSwgc3BhbkF0dHJpYnV0ZXMgPSB7fSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gaGFuZGxlcldyYXBwZWQgKC4uLmFyZ3MpIHtcbiAgICAgICAgICAvKiogQHR5cGUge0Zhc3RpZnlPdGVsSW5zdHJ1bWVudGF0aW9ufSAqL1xuICAgICAgICAgIGNvbnN0IGluc3RydW1lbnRhdGlvbiA9IHRoaXNba0luc3RydW1lbnRhdGlvbl1cblxuICAgICAgICAgIGNvbnN0IHJlcXVlc3QgPSBnZXRSZXF1ZXN0RnJvbUFyZ3MoYXJncylcbiAgICAgICAgICBpZiAocmVxdWVzdCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgaW5zdHJ1bWVudGF0aW9uLmxvZ2dlci5kZWJ1ZyhcbiAgICAgICAgICAgICAgYElnbm9yaW5nIHJvdXRlIGluc3RydW1lbnRhdGlvbiBiZWNhdXNlICR7aG9va05hbWV9IHdhcyBjYWxsZWQgd2l0aG91dCBhIEZhc3RpZnkgcmVxdWVzdCBhcmd1bWVudGBcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIHJldHVybiBoYW5kbGVyLmNhbGwodGhpcywgLi4uYXJncylcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoaW5zdHJ1bWVudGF0aW9uLmlzRW5hYmxlZCgpID09PSBmYWxzZSB8fCByZXF1ZXN0LnJvdXRlT3B0aW9ucy5jb25maWc/Lm90ZWwgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICBpbnN0cnVtZW50YXRpb24ubG9nZ2VyLmRlYnVnKFxuICAgICAgICAgICAgICBgSWdub3Jpbmcgcm91dGUgaW5zdHJ1bWVudGF0aW9uICR7cmVxdWVzdC5yb3V0ZU9wdGlvbnMubWV0aG9kfSAke3JlcXVlc3Qucm91dGVPcHRpb25zLnVybH0gYmVjYXVzZSBpdCBpcyBkaXNhYmxlZGBcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIHJldHVybiBoYW5kbGVyLmNhbGwodGhpcywgLi4uYXJncylcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoaW5zdHJ1bWVudGF0aW9uW2tJZ25vcmVQYXRoc10/Lih7XG4gICAgICAgICAgICB1cmw6IHJlcXVlc3QudXJsLFxuICAgICAgICAgICAgbWV0aG9kOiByZXF1ZXN0Lm1ldGhvZCxcbiAgICAgICAgICB9KSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgaW5zdHJ1bWVudGF0aW9uLmxvZ2dlci5kZWJ1ZyhcbiAgICAgICAgICAgICAgYElnbm9yaW5nIHJvdXRlIGluc3RydW1lbnRhdGlvbiAke3JlcXVlc3Qucm91dGVPcHRpb25zLm1ldGhvZH0gJHtyZXF1ZXN0LnJvdXRlT3B0aW9ucy51cmx9IGJlY2F1c2UgaXQgbWF0Y2hlcyB0aGUgaWdub3JlIHBhdGhgXG4gICAgICAgICAgICApXG4gICAgICAgICAgICByZXR1cm4gaGFuZGxlci5jYWxsKHRoaXMsIC4uLmFyZ3MpXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLyogYzggaWdub3JlIG5leHQgKi9cbiAgICAgICAgICBjb25zdCBjdHggPSByZXF1ZXN0W2tSZXF1ZXN0Q29udGV4dF0gPz8gY29udGV4dC5hY3RpdmUoKVxuICAgICAgICAgIGNvbnN0IGhhbmRsZXJOYW1lID0gaGFuZGxlci5uYW1lPy5sZW5ndGggPiAwXG4gICAgICAgICAgICA/IGhhbmRsZXIubmFtZVxuICAgICAgICAgICAgOiB0aGlzLnBsdWdpbk5hbWUgLyogYzggaWdub3JlIG5leHQgKi8gPz8gQU5PTllNT1VTX0ZVTkNUSU9OX05BTUUgLyogYzggaWdub3JlIG5leHQgKi9cblxuICAgICAgICAgIGNvbnN0IHNwYW4gPSBpbnN0cnVtZW50YXRpb24udHJhY2VyLnN0YXJ0U3BhbihcbiAgICAgICAgICAgIGAke2hvb2tOYW1lfSAtICR7aGFuZGxlck5hbWV9YCxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgYXR0cmlidXRlczogc3BhbkF0dHJpYnV0ZXNcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjdHhcbiAgICAgICAgICApXG5cbiAgICAgICAgICBpZiAoaW5zdHJ1bWVudGF0aW9uLl9saWZlY3ljbGVIb29rICE9IG51bGwpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGluc3RydW1lbnRhdGlvbi5fbGlmZWN5Y2xlSG9vayhzcGFuLCB7XG4gICAgICAgICAgICAgICAgaG9va05hbWUsXG4gICAgICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgICAgICBoYW5kbGVyOiBoYW5kbGVyTmFtZVxuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgIGluc3RydW1lbnRhdGlvbi5sb2dnZXIuZXJyb3IoeyBlcnIgfSwgJ0V4ZWN1dGlvbiBvZiBsaWZlY3ljbGVIb29rIGZhaWxlZCcpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIGNvbnRleHQud2l0aChcbiAgICAgICAgICAgIHRyYWNlLnNldFNwYW4oY3R4LCBzcGFuKSxcbiAgICAgICAgICAgIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25zdCByZXMgPSBoYW5kbGVyLmNhbGwodGhpcywgLi4uYXJncylcblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgcmVzPy50aGVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gcmVzLnRoZW4oXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgc3Bhbi5lbmQoKVxuICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHRcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgIHNwYW4uc2V0U3RhdHVzKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFNwYW5TdGF0dXNDb2RlLkVSUk9SLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogZXJyb3IubWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgaWYgKGluc3RydW1lbnRhdGlvbltrUmVjb3JkRXhjZXB0aW9uc10gIT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzcGFuLnJlY29yZEV4Y2VwdGlvbihlcnJvcilcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgc3Bhbi5lbmQoKVxuICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlcnJvcilcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHNwYW4uZW5kKClcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzXG4gICAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgc3Bhbi5zZXRTdGF0dXMoe1xuICAgICAgICAgICAgICAgICAgY29kZTogU3BhblN0YXR1c0NvZGUuRVJST1IsXG4gICAgICAgICAgICAgICAgICBtZXNzYWdlOiBlcnJvci5tZXNzYWdlXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICBpZiAoaW5zdHJ1bWVudGF0aW9uW2tSZWNvcmRFeGNlcHRpb25zXSAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICAgIHNwYW4ucmVjb3JkRXhjZXB0aW9uKGVycm9yKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBzcGFuLmVuZCgpXG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyb3JcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRoaXNcbiAgICAgICAgICApXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBGYXN0aWZ5T3RlbEluc3RydW1lbnRhdGlvblxubW9kdWxlLmV4cG9ydHMuRmFzdGlmeU90ZWxJbnN0cnVtZW50YXRpb24gPSBGYXN0aWZ5T3RlbEluc3RydW1lbnRhdGlvblxuIl0sIm5hbWVzIjpbXSwiaWdub3JlTGlzdCI6WzBdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///(ssr)/./node_modules/.pnpm/@fastify+otel@0.18.0_@opentelemetry+api@1.9.1/node_modules/@fastify/otel/index.js\n");
/***/ }),
/***/ "(ssr)/./node_modules/.pnpm/@fastify+otel@0.18.0_@opentelemetry+api@1.9.1/node_modules/@fastify/otel/package.json":
/*!******************************************************************************************************************!*\
!*** ./node_modules/.pnpm/@fastify+otel@0.18.0_@opentelemetry+api@1.9.1/node_modules/@fastify/otel/package.json ***!
\******************************************************************************************************************/
/***/ ((module) => {
module.exports = /*#__PURE__*/JSON.parse('{"name":"@fastify/otel","version":"0.18.0","description":"Official Fastify OpenTelemetry Instrumentation","main":"index.js","type":"commonjs","types":"types/index.d.ts","scripts":{"lint":"eslint","lint:fix":"eslint --fix","test":"npm run test:all && npm run test:typescript","test:unit":"c8 --100 node --test","test:all":"npm run test:v4 && npm run test:v5","test:v4":"cross-env FASTIFY_VERSION=fastifyv4 npm run test:unit","test:v5":"cross-env FASTIFY_VERSION=fastify npm run test:unit","test:coverage":"c8 node --test && c8 report --reporter=html","test:typescript":"tsd"},"repository":{"type":"git","url":"git+https://github.com/fastify/otel.git"},"keywords":["plugin","helper","fastify","instrumentation","otel","opentelemetry"],"author":"Carlos Fuentes - @metcoder95 (https://metcoder.dev)","license":"MIT","bugs":{"url":"https://github.com/fastify/otel/issues"},"homepage":"https://github.com/fastify/otel#readme","funding":[{"type":"github","url":"https://github.com/sponsors/fastify"},{"type":"opencollective","url":"https://opencollective.com/fastify"}],"devDependencies":{"@fastify/type-provider-typebox":"^6.1.0","@opentelemetry/context-async-hooks":"^2.0.0","@opentelemetry/contrib-test-utils":"^0.59.0","@opentelemetry/instrumentation-http":"^0.212.0","@opentelemetry/propagator-jaeger":"^2.0.0","@opentelemetry/sdk-trace-base":"^2.0.0","@opentelemetry/sdk-trace-node":"^2.2.0","@types/node":"^25.0.3","c8":"^11.0.0","cross-env":"^10.0.0","eslint":"^9.16.0","fastify":"^5.1.0","fastify-plugin":"^5.1.0","fastifyv4":"npm:fastify@^4.0.0","neostandard":"^0.12.0","tsd":"^0.33.0"},"dependencies":{"@opentelemetry/core":"^2.0.0","@opentelemetry/instrumentation":"^0.212.0","@opentelemetry/semantic-conventions":"^1.28.0","minimatch":"^10.2.4"},"peerDependencies":{"@opentelemetry/api":"^1.9.0"},"tsd":{"directory":"types"}}');
/***/ })
};
;