@sentry/node 9.33.0 → 9.34.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/index.js +48 -56
- package/build/cjs/index.js.map +1 -1
- package/build/cjs/integrations/featureFlagShims/launchDarkly.js +43 -0
- package/build/cjs/integrations/featureFlagShims/launchDarkly.js.map +1 -0
- package/build/cjs/integrations/featureFlagShims/openFeature.js +55 -0
- package/build/cjs/integrations/featureFlagShims/openFeature.js.map +1 -0
- package/build/cjs/integrations/featureFlagShims/statsig.js +23 -0
- package/build/cjs/integrations/featureFlagShims/statsig.js.map +1 -0
- package/build/cjs/integrations/featureFlagShims/unleash.js +23 -0
- package/build/cjs/integrations/featureFlagShims/unleash.js.map +1 -0
- package/build/cjs/integrations/fs.js +2 -2
- package/build/cjs/integrations/fs.js.map +1 -1
- package/build/cjs/integrations/http/index.js +7 -11
- package/build/cjs/integrations/http/index.js.map +1 -1
- package/build/cjs/integrations/node-fetch/index.js +4 -5
- package/build/cjs/integrations/node-fetch/index.js.map +1 -1
- package/build/cjs/integrations/tracing/amqplib.js +4 -5
- package/build/cjs/integrations/tracing/amqplib.js.map +1 -1
- package/build/cjs/integrations/tracing/connect.js +3 -4
- package/build/cjs/integrations/tracing/connect.js.map +1 -1
- package/build/cjs/integrations/tracing/dataloader.js +3 -3
- package/build/cjs/integrations/tracing/dataloader.js.map +1 -1
- package/build/cjs/integrations/tracing/express.js +5 -7
- package/build/cjs/integrations/tracing/express.js.map +1 -1
- package/build/cjs/integrations/tracing/fastify/fastify-otel/index.js +5 -10
- package/build/cjs/integrations/tracing/fastify/fastify-otel/index.js.map +1 -1
- package/build/cjs/integrations/tracing/fastify/index.js +6 -6
- package/build/cjs/integrations/tracing/fastify/index.js.map +1 -1
- package/build/cjs/integrations/tracing/genericPool.js +3 -3
- package/build/cjs/integrations/tracing/genericPool.js.map +1 -1
- package/build/cjs/integrations/tracing/graphql.js +3 -4
- package/build/cjs/integrations/tracing/graphql.js.map +1 -1
- package/build/cjs/integrations/tracing/hapi/index.js +3 -4
- package/build/cjs/integrations/tracing/hapi/index.js.map +1 -1
- package/build/cjs/integrations/tracing/kafka.js +4 -5
- package/build/cjs/integrations/tracing/kafka.js.map +1 -1
- package/build/cjs/integrations/tracing/knex.js +3 -3
- package/build/cjs/integrations/tracing/knex.js.map +1 -1
- package/build/cjs/integrations/tracing/koa.js +4 -6
- package/build/cjs/integrations/tracing/koa.js.map +1 -1
- package/build/cjs/integrations/tracing/lrumemoizer.js +2 -2
- package/build/cjs/integrations/tracing/lrumemoizer.js.map +1 -1
- package/build/cjs/integrations/tracing/mongo.js +3 -4
- package/build/cjs/integrations/tracing/mongo.js.map +1 -1
- package/build/cjs/integrations/tracing/mongoose.js +3 -4
- package/build/cjs/integrations/tracing/mongoose.js.map +1 -1
- package/build/cjs/integrations/tracing/mysql.js +2 -2
- package/build/cjs/integrations/tracing/mysql.js.map +1 -1
- package/build/cjs/integrations/tracing/mysql2.js +3 -4
- package/build/cjs/integrations/tracing/mysql2.js.map +1 -1
- package/build/cjs/integrations/tracing/postgres.js +3 -4
- package/build/cjs/integrations/tracing/postgres.js.map +1 -1
- package/build/cjs/integrations/tracing/postgresjs.js +3 -4
- package/build/cjs/integrations/tracing/postgresjs.js.map +1 -1
- package/build/cjs/integrations/tracing/prisma.js +2 -2
- package/build/cjs/integrations/tracing/prisma.js.map +1 -1
- package/build/cjs/integrations/tracing/redis.js +3 -3
- package/build/cjs/integrations/tracing/redis.js.map +1 -1
- package/build/cjs/integrations/tracing/tedious.js +3 -3
- package/build/cjs/integrations/tracing/tedious.js.map +1 -1
- package/build/cjs/integrations/tracing/vercelai/index.js +2 -2
- package/build/cjs/integrations/tracing/vercelai/index.js.map +1 -1
- package/build/cjs/preload.js +2 -2
- package/build/cjs/preload.js.map +1 -1
- package/build/cjs/sdk/index.js +22 -203
- package/build/cjs/sdk/index.js.map +1 -1
- package/build/cjs/sdk/initOtel.js +4 -22
- package/build/cjs/sdk/initOtel.js.map +1 -1
- package/build/esm/index.js +6 -21
- package/build/esm/index.js.map +1 -1
- package/build/esm/integrations/featureFlagShims/launchDarkly.js +40 -0
- package/build/esm/integrations/featureFlagShims/launchDarkly.js.map +1 -0
- package/build/esm/integrations/featureFlagShims/openFeature.js +52 -0
- package/build/esm/integrations/featureFlagShims/openFeature.js.map +1 -0
- package/build/esm/integrations/featureFlagShims/statsig.js +21 -0
- package/build/esm/integrations/featureFlagShims/statsig.js.map +1 -0
- package/build/esm/integrations/featureFlagShims/unleash.js +21 -0
- package/build/esm/integrations/featureFlagShims/unleash.js.map +1 -0
- package/build/esm/integrations/fs.js +1 -1
- package/build/esm/integrations/fs.js.map +1 -1
- package/build/esm/integrations/http/index.js +1 -5
- package/build/esm/integrations/http/index.js.map +1 -1
- package/build/esm/integrations/node-fetch/index.js +2 -3
- package/build/esm/integrations/node-fetch/index.js.map +1 -1
- package/build/esm/integrations/tracing/amqplib.js +1 -2
- package/build/esm/integrations/tracing/amqplib.js.map +1 -1
- package/build/esm/integrations/tracing/connect.js +1 -2
- package/build/esm/integrations/tracing/connect.js.map +1 -1
- package/build/esm/integrations/tracing/dataloader.js +1 -1
- package/build/esm/integrations/tracing/dataloader.js.map +1 -1
- package/build/esm/integrations/tracing/express.js +2 -4
- package/build/esm/integrations/tracing/express.js.map +1 -1
- package/build/esm/integrations/tracing/fastify/fastify-otel/index.js +5 -10
- package/build/esm/integrations/tracing/fastify/fastify-otel/index.js.map +1 -1
- package/build/esm/integrations/tracing/fastify/index.js +5 -5
- package/build/esm/integrations/tracing/fastify/index.js.map +1 -1
- package/build/esm/integrations/tracing/genericPool.js +1 -1
- package/build/esm/integrations/tracing/genericPool.js.map +1 -1
- package/build/esm/integrations/tracing/graphql.js +2 -3
- package/build/esm/integrations/tracing/graphql.js.map +1 -1
- package/build/esm/integrations/tracing/hapi/index.js +1 -2
- package/build/esm/integrations/tracing/hapi/index.js.map +1 -1
- package/build/esm/integrations/tracing/kafka.js +1 -2
- package/build/esm/integrations/tracing/kafka.js.map +1 -1
- package/build/esm/integrations/tracing/knex.js +1 -1
- package/build/esm/integrations/tracing/knex.js.map +1 -1
- package/build/esm/integrations/tracing/koa.js +2 -4
- package/build/esm/integrations/tracing/koa.js.map +1 -1
- package/build/esm/integrations/tracing/lrumemoizer.js +1 -1
- package/build/esm/integrations/tracing/lrumemoizer.js.map +1 -1
- package/build/esm/integrations/tracing/mongo.js +1 -2
- package/build/esm/integrations/tracing/mongo.js.map +1 -1
- package/build/esm/integrations/tracing/mongoose.js +1 -2
- package/build/esm/integrations/tracing/mongoose.js.map +1 -1
- package/build/esm/integrations/tracing/mysql.js +1 -1
- package/build/esm/integrations/tracing/mysql.js.map +1 -1
- package/build/esm/integrations/tracing/mysql2.js +1 -2
- package/build/esm/integrations/tracing/mysql2.js.map +1 -1
- package/build/esm/integrations/tracing/postgres.js +1 -2
- package/build/esm/integrations/tracing/postgres.js.map +1 -1
- package/build/esm/integrations/tracing/postgresjs.js +2 -3
- package/build/esm/integrations/tracing/postgresjs.js.map +1 -1
- package/build/esm/integrations/tracing/prisma.js +1 -1
- package/build/esm/integrations/tracing/prisma.js.map +1 -1
- package/build/esm/integrations/tracing/redis.js +1 -1
- package/build/esm/integrations/tracing/redis.js.map +1 -1
- package/build/esm/integrations/tracing/tedious.js +1 -1
- package/build/esm/integrations/tracing/tedious.js.map +1 -1
- package/build/esm/integrations/tracing/vercelai/index.js +1 -1
- package/build/esm/integrations/tracing/vercelai/index.js.map +1 -1
- package/build/esm/package.json +1 -1
- package/build/esm/preload.js +1 -1
- package/build/esm/preload.js.map +1 -1
- package/build/esm/sdk/index.js +22 -202
- package/build/esm/sdk/index.js.map +1 -1
- package/build/esm/sdk/initOtel.js +3 -21
- package/build/esm/sdk/initOtel.js.map +1 -1
- package/build/types/index.d.ts +3 -21
- package/build/types/index.d.ts.map +1 -1
- package/build/types/integrations/featureFlagShims/index.d.ts +5 -0
- package/build/types/integrations/featureFlagShims/index.d.ts.map +1 -0
- package/build/types/integrations/featureFlagShims/launchDarkly.d.ts +10 -0
- package/build/types/integrations/featureFlagShims/launchDarkly.d.ts.map +1 -0
- package/build/types/integrations/featureFlagShims/openFeature.d.ts +23 -0
- package/build/types/integrations/featureFlagShims/openFeature.d.ts.map +1 -0
- package/build/types/integrations/featureFlagShims/statsig.d.ts +6 -0
- package/build/types/integrations/featureFlagShims/statsig.d.ts.map +1 -0
- package/build/types/integrations/featureFlagShims/unleash.d.ts +6 -0
- package/build/types/integrations/featureFlagShims/unleash.d.ts.map +1 -0
- package/build/types/integrations/http/index.d.ts +1 -1
- package/build/types/integrations/http/index.d.ts.map +1 -1
- package/build/types/integrations/node-fetch/index.d.ts.map +1 -1
- package/build/types/integrations/tracing/amqplib.d.ts.map +1 -1
- package/build/types/integrations/tracing/connect.d.ts.map +1 -1
- package/build/types/integrations/tracing/express.d.ts.map +1 -1
- package/build/types/integrations/tracing/graphql.d.ts.map +1 -1
- package/build/types/integrations/tracing/hapi/index.d.ts.map +1 -1
- package/build/types/integrations/tracing/kafka.d.ts.map +1 -1
- package/build/types/integrations/tracing/koa.d.ts.map +1 -1
- package/build/types/integrations/tracing/mongo.d.ts.map +1 -1
- package/build/types/integrations/tracing/mongoose.d.ts.map +1 -1
- package/build/types/integrations/tracing/mysql2.d.ts.map +1 -1
- package/build/types/integrations/tracing/postgres.d.ts.map +1 -1
- package/build/types/integrations/tracing/postgresjs.d.ts.map +1 -1
- package/build/types/integrations/tracing/vercelai/index.d.ts.map +1 -1
- package/build/types/sdk/index.d.ts +2 -6
- package/build/types/sdk/index.d.ts.map +1 -1
- package/build/types/sdk/initOtel.d.ts +1 -1
- package/build/types/sdk/initOtel.d.ts.map +1 -1
- package/build/types/types.d.ts +1 -1
- package/build/types/types.d.ts.map +1 -1
- package/build/types-ts3.8/index.d.ts +3 -21
- package/build/types-ts3.8/integrations/featureFlagShims/index.d.ts +5 -0
- package/build/types-ts3.8/integrations/featureFlagShims/launchDarkly.d.ts +10 -0
- package/build/types-ts3.8/integrations/featureFlagShims/openFeature.d.ts +23 -0
- package/build/types-ts3.8/integrations/featureFlagShims/statsig.d.ts +6 -0
- package/build/types-ts3.8/integrations/featureFlagShims/unleash.d.ts +6 -0
- package/build/types-ts3.8/integrations/http/index.d.ts +1 -1
- package/build/types-ts3.8/sdk/index.d.ts +2 -6
- package/build/types-ts3.8/sdk/initOtel.d.ts +1 -1
- package/build/types-ts3.8/types.d.ts +1 -1
- package/package.json +4 -3
- package/build/cjs/cron/common.js +0 -56
- package/build/cjs/cron/common.js.map +0 -1
- package/build/cjs/cron/cron.js +0 -112
- package/build/cjs/cron/cron.js.map +0 -1
- package/build/cjs/cron/index.js +0 -15
- package/build/cjs/cron/index.js.map +0 -1
- package/build/cjs/cron/node-cron.js +0 -71
- package/build/cjs/cron/node-cron.js.map +0 -1
- package/build/cjs/cron/node-schedule.js +0 -65
- package/build/cjs/cron/node-schedule.js.map +0 -1
- package/build/cjs/integrations/anr/index.js +0 -238
- package/build/cjs/integrations/anr/index.js.map +0 -1
- package/build/cjs/integrations/childProcess.js +0 -100
- package/build/cjs/integrations/childProcess.js.map +0 -1
- package/build/cjs/integrations/context.js +0 -457
- package/build/cjs/integrations/context.js.map +0 -1
- package/build/cjs/integrations/contextlines.js +0 -405
- package/build/cjs/integrations/contextlines.js.map +0 -1
- package/build/cjs/integrations/http/SentryHttpInstrumentation.js +0 -558
- package/build/cjs/integrations/http/SentryHttpInstrumentation.js.map +0 -1
- package/build/cjs/integrations/local-variables/common.js +0 -69
- package/build/cjs/integrations/local-variables/common.js.map +0 -1
- package/build/cjs/integrations/local-variables/index.js +0 -12
- package/build/cjs/integrations/local-variables/index.js.map +0 -1
- package/build/cjs/integrations/local-variables/local-variables-async.js +0 -143
- package/build/cjs/integrations/local-variables/local-variables-async.js.map +0 -1
- package/build/cjs/integrations/local-variables/local-variables-sync.js +0 -410
- package/build/cjs/integrations/local-variables/local-variables-sync.js.map +0 -1
- package/build/cjs/integrations/modules.js +0 -135
- package/build/cjs/integrations/modules.js.map +0 -1
- package/build/cjs/integrations/node-fetch/SentryNodeFetchInstrumentation.js +0 -291
- package/build/cjs/integrations/node-fetch/SentryNodeFetchInstrumentation.js.map +0 -1
- package/build/cjs/integrations/onuncaughtexception.js +0 -134
- package/build/cjs/integrations/onuncaughtexception.js.map +0 -1
- package/build/cjs/integrations/onunhandledrejection.js +0 -89
- package/build/cjs/integrations/onunhandledrejection.js.map +0 -1
- package/build/cjs/integrations/processSession.js +0 -36
- package/build/cjs/integrations/processSession.js.map +0 -1
- package/build/cjs/integrations/spotlight.js +0 -101
- package/build/cjs/integrations/spotlight.js.map +0 -1
- package/build/cjs/integrations/winston.js +0 -151
- package/build/cjs/integrations/winston.js.map +0 -1
- package/build/cjs/logs/capture.js +0 -29
- package/build/cjs/logs/capture.js.map +0 -1
- package/build/cjs/logs/exports.js +0 -178
- package/build/cjs/logs/exports.js.map +0 -1
- package/build/cjs/nodeVersion.js +0 -12
- package/build/cjs/nodeVersion.js.map +0 -1
- package/build/cjs/otel/contextManager.js +0 -16
- package/build/cjs/otel/contextManager.js.map +0 -1
- package/build/cjs/otel/instrument.js +0 -139
- package/build/cjs/otel/instrument.js.map +0 -1
- package/build/cjs/proxy/base.js +0 -122
- package/build/cjs/proxy/base.js.map +0 -1
- package/build/cjs/proxy/index.js +0 -173
- package/build/cjs/proxy/index.js.map +0 -1
- package/build/cjs/proxy/parse-proxy-response.js +0 -104
- package/build/cjs/proxy/parse-proxy-response.js.map +0 -1
- package/build/cjs/sdk/api.js +0 -117
- package/build/cjs/sdk/api.js.map +0 -1
- package/build/cjs/sdk/client.js +0 -156
- package/build/cjs/sdk/client.js.map +0 -1
- package/build/cjs/transports/http.js +0 -158
- package/build/cjs/transports/http.js.map +0 -1
- package/build/cjs/utils/addOriginToSpan.js +0 -11
- package/build/cjs/utils/addOriginToSpan.js.map +0 -1
- package/build/cjs/utils/baggage.js +0 -36
- package/build/cjs/utils/baggage.js.map +0 -1
- package/build/cjs/utils/commonjs.js +0 -13
- package/build/cjs/utils/commonjs.js.map +0 -1
- package/build/cjs/utils/createMissingInstrumentationContext.js +0 -11
- package/build/cjs/utils/createMissingInstrumentationContext.js.map +0 -1
- package/build/cjs/utils/debug.js +0 -23
- package/build/cjs/utils/debug.js.map +0 -1
- package/build/cjs/utils/ensureIsWrapped.js +0 -41
- package/build/cjs/utils/ensureIsWrapped.js.map +0 -1
- package/build/cjs/utils/envToBool.js +0 -32
- package/build/cjs/utils/envToBool.js.map +0 -1
- package/build/cjs/utils/errorhandling.js +0 -42
- package/build/cjs/utils/errorhandling.js.map +0 -1
- package/build/cjs/utils/getRequestUrl.js +0 -18
- package/build/cjs/utils/getRequestUrl.js.map +0 -1
- package/build/cjs/utils/module.js +0 -60
- package/build/cjs/utils/module.js.map +0 -1
- package/build/esm/cron/common.js +0 -54
- package/build/esm/cron/common.js.map +0 -1
- package/build/esm/cron/cron.js +0 -110
- package/build/esm/cron/cron.js.map +0 -1
- package/build/esm/cron/index.js +0 -13
- package/build/esm/cron/index.js.map +0 -1
- package/build/esm/cron/node-cron.js +0 -69
- package/build/esm/cron/node-cron.js.map +0 -1
- package/build/esm/cron/node-schedule.js +0 -63
- package/build/esm/cron/node-schedule.js.map +0 -1
- package/build/esm/integrations/anr/index.js +0 -234
- package/build/esm/integrations/anr/index.js.map +0 -1
- package/build/esm/integrations/anr/worker-script.js +0 -2
- package/build/esm/integrations/childProcess.js +0 -98
- package/build/esm/integrations/childProcess.js.map +0 -1
- package/build/esm/integrations/context.js +0 -451
- package/build/esm/integrations/context.js.map +0 -1
- package/build/esm/integrations/contextlines.js +0 -399
- package/build/esm/integrations/contextlines.js.map +0 -1
- package/build/esm/integrations/http/SentryHttpInstrumentation.js +0 -555
- package/build/esm/integrations/http/SentryHttpInstrumentation.js.map +0 -1
- package/build/esm/integrations/local-variables/common.js +0 -64
- package/build/esm/integrations/local-variables/common.js.map +0 -1
- package/build/esm/integrations/local-variables/index.js +0 -10
- package/build/esm/integrations/local-variables/index.js.map +0 -1
- package/build/esm/integrations/local-variables/local-variables-async.js +0 -140
- package/build/esm/integrations/local-variables/local-variables-async.js.map +0 -1
- package/build/esm/integrations/local-variables/local-variables-sync.js +0 -405
- package/build/esm/integrations/local-variables/local-variables-sync.js.map +0 -1
- package/build/esm/integrations/local-variables/worker-script.js +0 -2
- package/build/esm/integrations/modules.js +0 -133
- package/build/esm/integrations/modules.js.map +0 -1
- package/build/esm/integrations/node-fetch/SentryNodeFetchInstrumentation.js +0 -289
- package/build/esm/integrations/node-fetch/SentryNodeFetchInstrumentation.js.map +0 -1
- package/build/esm/integrations/onuncaughtexception.js +0 -131
- package/build/esm/integrations/onuncaughtexception.js.map +0 -1
- package/build/esm/integrations/onunhandledrejection.js +0 -86
- package/build/esm/integrations/onunhandledrejection.js.map +0 -1
- package/build/esm/integrations/processSession.js +0 -34
- package/build/esm/integrations/processSession.js.map +0 -1
- package/build/esm/integrations/spotlight.js +0 -98
- package/build/esm/integrations/spotlight.js.map +0 -1
- package/build/esm/integrations/winston.js +0 -149
- package/build/esm/integrations/winston.js.map +0 -1
- package/build/esm/logs/capture.js +0 -27
- package/build/esm/logs/capture.js.map +0 -1
- package/build/esm/logs/exports.js +0 -170
- package/build/esm/logs/exports.js.map +0 -1
- package/build/esm/nodeVersion.js +0 -8
- package/build/esm/nodeVersion.js.map +0 -1
- package/build/esm/otel/contextManager.js +0 -14
- package/build/esm/otel/contextManager.js.map +0 -1
- package/build/esm/otel/instrument.js +0 -135
- package/build/esm/otel/instrument.js.map +0 -1
- package/build/esm/proxy/base.js +0 -120
- package/build/esm/proxy/base.js.map +0 -1
- package/build/esm/proxy/index.js +0 -171
- package/build/esm/proxy/index.js.map +0 -1
- package/build/esm/proxy/parse-proxy-response.js +0 -102
- package/build/esm/proxy/parse-proxy-response.js.map +0 -1
- package/build/esm/sdk/api.js +0 -114
- package/build/esm/sdk/api.js.map +0 -1
- package/build/esm/sdk/client.js +0 -154
- package/build/esm/sdk/client.js.map +0 -1
- package/build/esm/transports/http.js +0 -156
- package/build/esm/transports/http.js.map +0 -1
- package/build/esm/utils/addOriginToSpan.js +0 -9
- package/build/esm/utils/addOriginToSpan.js.map +0 -1
- package/build/esm/utils/baggage.js +0 -34
- package/build/esm/utils/baggage.js.map +0 -1
- package/build/esm/utils/commonjs.js +0 -11
- package/build/esm/utils/commonjs.js.map +0 -1
- package/build/esm/utils/createMissingInstrumentationContext.js +0 -9
- package/build/esm/utils/createMissingInstrumentationContext.js.map +0 -1
- package/build/esm/utils/debug.js +0 -21
- package/build/esm/utils/debug.js.map +0 -1
- package/build/esm/utils/ensureIsWrapped.js +0 -39
- package/build/esm/utils/ensureIsWrapped.js.map +0 -1
- package/build/esm/utils/envToBool.js +0 -28
- package/build/esm/utils/envToBool.js.map +0 -1
- package/build/esm/utils/errorhandling.js +0 -40
- package/build/esm/utils/errorhandling.js.map +0 -1
- package/build/esm/utils/getRequestUrl.js +0 -16
- package/build/esm/utils/getRequestUrl.js.map +0 -1
- package/build/esm/utils/module.js +0 -58
- package/build/esm/utils/module.js.map +0 -1
- package/build/types/cron/common.d.ts +0 -5
- package/build/types/cron/common.d.ts.map +0 -1
- package/build/types/cron/cron.d.ts +0 -43
- package/build/types/cron/cron.d.ts.map +0 -1
- package/build/types/cron/index.d.ts +0 -10
- package/build/types/cron/index.d.ts.map +0 -1
- package/build/types/cron/node-cron.d.ts +0 -27
- package/build/types/cron/node-cron.d.ts.map +0 -1
- package/build/types/cron/node-schedule.d.ts +0 -19
- package/build/types/cron/node-schedule.d.ts.map +0 -1
- package/build/types/integrations/anr/common.d.ts +0 -52
- package/build/types/integrations/anr/common.d.ts.map +0 -1
- package/build/types/integrations/anr/index.d.ts +0 -13
- package/build/types/integrations/anr/index.d.ts.map +0 -1
- package/build/types/integrations/anr/worker.d.ts +0 -2
- package/build/types/integrations/anr/worker.d.ts.map +0 -1
- package/build/types/integrations/childProcess.d.ts +0 -20
- package/build/types/integrations/childProcess.d.ts.map +0 -1
- package/build/types/integrations/context.d.ts +0 -30
- package/build/types/integrations/context.d.ts.map +0 -1
- package/build/types/integrations/contextlines.d.ts +0 -31
- package/build/types/integrations/contextlines.d.ts.map +0 -1
- package/build/types/integrations/http/SentryHttpInstrumentation.d.ts +0 -131
- package/build/types/integrations/http/SentryHttpInstrumentation.d.ts.map +0 -1
- package/build/types/integrations/local-variables/common.d.ts +0 -66
- package/build/types/integrations/local-variables/common.d.ts.map +0 -1
- package/build/types/integrations/local-variables/index.d.ts +0 -4
- package/build/types/integrations/local-variables/index.d.ts.map +0 -1
- package/build/types/integrations/local-variables/local-variables-async.d.ts +0 -7
- package/build/types/integrations/local-variables/local-variables-async.d.ts.map +0 -1
- package/build/types/integrations/local-variables/local-variables-sync.d.ts +0 -34
- package/build/types/integrations/local-variables/local-variables-sync.d.ts.map +0 -1
- package/build/types/integrations/local-variables/worker.d.ts +0 -2
- package/build/types/integrations/local-variables/worker.d.ts.map +0 -1
- package/build/types/integrations/modules.d.ts +0 -17
- package/build/types/integrations/modules.d.ts.map +0 -1
- package/build/types/integrations/node-fetch/SentryNodeFetchInstrumentation.d.ts +0 -56
- package/build/types/integrations/node-fetch/SentryNodeFetchInstrumentation.d.ts.map +0 -1
- package/build/types/integrations/onuncaughtexception.d.ts +0 -31
- package/build/types/integrations/onuncaughtexception.d.ts.map +0 -1
- package/build/types/integrations/onunhandledrejection.d.ts +0 -23
- package/build/types/integrations/onunhandledrejection.d.ts.map +0 -1
- package/build/types/integrations/processSession.d.ts +0 -5
- package/build/types/integrations/processSession.d.ts.map +0 -1
- package/build/types/integrations/spotlight.d.ts +0 -18
- package/build/types/integrations/spotlight.d.ts.map +0 -1
- package/build/types/integrations/winston.d.ts +0 -44
- package/build/types/integrations/winston.d.ts.map +0 -1
- package/build/types/logs/capture.d.ts +0 -11
- package/build/types/logs/capture.d.ts.map +0 -1
- package/build/types/logs/exports.d.ts +0 -150
- package/build/types/logs/exports.d.ts.map +0 -1
- package/build/types/nodeVersion.d.ts +0 -8
- package/build/types/nodeVersion.d.ts.map +0 -1
- package/build/types/otel/contextManager.d.ts +0 -10
- package/build/types/otel/contextManager.d.ts.map +0 -1
- package/build/types/otel/instrument.d.ts +0 -23
- package/build/types/otel/instrument.d.ts.map +0 -1
- package/build/types/proxy/base.d.ts +0 -65
- package/build/types/proxy/base.d.ts.map +0 -1
- package/build/types/proxy/helpers.d.ts +0 -42
- package/build/types/proxy/helpers.d.ts.map +0 -1
- package/build/types/proxy/index.d.ts +0 -73
- package/build/types/proxy/index.d.ts.map +0 -1
- package/build/types/proxy/parse-proxy-response.d.ts +0 -43
- package/build/types/proxy/parse-proxy-response.d.ts.map +0 -1
- package/build/types/sdk/api.d.ts +0 -8
- package/build/types/sdk/api.d.ts.map +0 -1
- package/build/types/sdk/client.d.ts +0 -29
- package/build/types/sdk/client.d.ts.map +0 -1
- package/build/types/sdk/scope.d.ts +0 -7
- package/build/types/sdk/scope.d.ts.map +0 -1
- package/build/types/transports/http-module.d.ts +0 -31
- package/build/types/transports/http-module.d.ts.map +0 -1
- package/build/types/transports/http.d.ts +0 -21
- package/build/types/transports/http.d.ts.map +0 -1
- package/build/types/transports/index.d.ts +0 -3
- package/build/types/transports/index.d.ts.map +0 -1
- package/build/types/utils/addOriginToSpan.d.ts +0 -5
- package/build/types/utils/addOriginToSpan.d.ts.map +0 -1
- package/build/types/utils/baggage.d.ts +0 -6
- package/build/types/utils/baggage.d.ts.map +0 -1
- package/build/types/utils/commonjs.d.ts +0 -3
- package/build/types/utils/commonjs.d.ts.map +0 -1
- package/build/types/utils/createMissingInstrumentationContext.d.ts +0 -3
- package/build/types/utils/createMissingInstrumentationContext.d.ts.map +0 -1
- package/build/types/utils/debug.d.ts +0 -5
- package/build/types/utils/debug.d.ts.map +0 -1
- package/build/types/utils/ensureIsWrapped.d.ts +0 -5
- package/build/types/utils/ensureIsWrapped.d.ts.map +0 -1
- package/build/types/utils/entry-point.d.ts +0 -24
- package/build/types/utils/entry-point.d.ts.map +0 -1
- package/build/types/utils/envToBool.d.ts +0 -13
- package/build/types/utils/envToBool.d.ts.map +0 -1
- package/build/types/utils/errorhandling.d.ts +0 -5
- package/build/types/utils/errorhandling.d.ts.map +0 -1
- package/build/types/utils/getRequestUrl.d.ts +0 -5
- package/build/types/utils/getRequestUrl.d.ts.map +0 -1
- package/build/types/utils/module.d.ts +0 -3
- package/build/types/utils/module.d.ts.map +0 -1
- package/build/types/utils/prepareEvent.d.ts +0 -17
- package/build/types/utils/prepareEvent.d.ts.map +0 -1
- package/build/types-ts3.8/cron/common.d.ts +0 -5
- package/build/types-ts3.8/cron/cron.d.ts +0 -43
- package/build/types-ts3.8/cron/index.d.ts +0 -10
- package/build/types-ts3.8/cron/node-cron.d.ts +0 -27
- package/build/types-ts3.8/cron/node-schedule.d.ts +0 -19
- package/build/types-ts3.8/integrations/anr/common.d.ts +0 -52
- package/build/types-ts3.8/integrations/anr/index.d.ts +0 -13
- package/build/types-ts3.8/integrations/anr/worker.d.ts +0 -2
- package/build/types-ts3.8/integrations/childProcess.d.ts +0 -20
- package/build/types-ts3.8/integrations/context.d.ts +0 -30
- package/build/types-ts3.8/integrations/contextlines.d.ts +0 -31
- package/build/types-ts3.8/integrations/http/SentryHttpInstrumentation.d.ts +0 -133
- package/build/types-ts3.8/integrations/local-variables/common.d.ts +0 -66
- package/build/types-ts3.8/integrations/local-variables/index.d.ts +0 -4
- package/build/types-ts3.8/integrations/local-variables/local-variables-async.d.ts +0 -7
- package/build/types-ts3.8/integrations/local-variables/local-variables-sync.d.ts +0 -34
- package/build/types-ts3.8/integrations/local-variables/worker.d.ts +0 -2
- package/build/types-ts3.8/integrations/modules.d.ts +0 -17
- package/build/types-ts3.8/integrations/node-fetch/SentryNodeFetchInstrumentation.d.ts +0 -56
- package/build/types-ts3.8/integrations/onuncaughtexception.d.ts +0 -31
- package/build/types-ts3.8/integrations/onunhandledrejection.d.ts +0 -23
- package/build/types-ts3.8/integrations/processSession.d.ts +0 -5
- package/build/types-ts3.8/integrations/spotlight.d.ts +0 -18
- package/build/types-ts3.8/integrations/winston.d.ts +0 -44
- package/build/types-ts3.8/logs/capture.d.ts +0 -18
- package/build/types-ts3.8/logs/exports.d.ts +0 -150
- package/build/types-ts3.8/nodeVersion.d.ts +0 -8
- package/build/types-ts3.8/otel/contextManager.d.ts +0 -10
- package/build/types-ts3.8/otel/instrument.d.ts +0 -23
- package/build/types-ts3.8/proxy/base.d.ts +0 -60
- package/build/types-ts3.8/proxy/helpers.d.ts +0 -38
- package/build/types-ts3.8/proxy/index.d.ts +0 -74
- package/build/types-ts3.8/proxy/parse-proxy-response.d.ts +0 -40
- package/build/types-ts3.8/sdk/api.d.ts +0 -8
- package/build/types-ts3.8/sdk/client.d.ts +0 -32
- package/build/types-ts3.8/sdk/scope.d.ts +0 -7
- package/build/types-ts3.8/transports/http-module.d.ts +0 -28
- package/build/types-ts3.8/transports/http.d.ts +0 -20
- package/build/types-ts3.8/transports/index.d.ts +0 -3
- package/build/types-ts3.8/utils/addOriginToSpan.d.ts +0 -5
- package/build/types-ts3.8/utils/baggage.d.ts +0 -6
- package/build/types-ts3.8/utils/commonjs.d.ts +0 -3
- package/build/types-ts3.8/utils/createMissingInstrumentationContext.d.ts +0 -3
- package/build/types-ts3.8/utils/debug.d.ts +0 -5
- package/build/types-ts3.8/utils/ensureIsWrapped.d.ts +0 -5
- package/build/types-ts3.8/utils/entry-point.d.ts +0 -24
- package/build/types-ts3.8/utils/envToBool.d.ts +0 -13
- package/build/types-ts3.8/utils/errorhandling.d.ts +0 -5
- package/build/types-ts3.8/utils/getRequestUrl.d.ts +0 -5
- package/build/types-ts3.8/utils/module.d.ts +0 -3
- package/build/types-ts3.8/utils/prepareEvent.d.ts +0 -17
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
|
|
3
|
-
const core = require('@sentry/core');
|
|
4
|
-
const common = require('./common.js');
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Instruments the `node-schedule` library to send a check-in event to Sentry for each job execution.
|
|
8
|
-
*
|
|
9
|
-
* ```ts
|
|
10
|
-
* import * as Sentry from '@sentry/node';
|
|
11
|
-
* import * as schedule from 'node-schedule';
|
|
12
|
-
*
|
|
13
|
-
* const scheduleWithCheckIn = Sentry.cron.instrumentNodeSchedule(schedule);
|
|
14
|
-
*
|
|
15
|
-
* const job = scheduleWithCheckIn.scheduleJob('my-cron-job', '* * * * *', () => {
|
|
16
|
-
* console.log('You will see this message every minute');
|
|
17
|
-
* });
|
|
18
|
-
* ```
|
|
19
|
-
*/
|
|
20
|
-
function instrumentNodeSchedule(lib) {
|
|
21
|
-
return new Proxy(lib, {
|
|
22
|
-
get(target, prop) {
|
|
23
|
-
if (prop === 'scheduleJob') {
|
|
24
|
-
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
25
|
-
return new Proxy(target.scheduleJob, {
|
|
26
|
-
apply(target, thisArg, argArray) {
|
|
27
|
-
const [nameOrExpression, expressionOrCallback, callback] = argArray;
|
|
28
|
-
|
|
29
|
-
if (
|
|
30
|
-
typeof nameOrExpression !== 'string' ||
|
|
31
|
-
typeof expressionOrCallback !== 'string' ||
|
|
32
|
-
typeof callback !== 'function'
|
|
33
|
-
) {
|
|
34
|
-
throw new Error(
|
|
35
|
-
"Automatic instrumentation of 'node-schedule' requires the first parameter of 'scheduleJob' to be a job name string and the second parameter to be a crontab string",
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const monitorSlug = nameOrExpression;
|
|
40
|
-
const expression = expressionOrCallback;
|
|
41
|
-
|
|
42
|
-
async function monitoredCallback() {
|
|
43
|
-
return core.withMonitor(
|
|
44
|
-
monitorSlug,
|
|
45
|
-
async () => {
|
|
46
|
-
await callback?.();
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
schedule: { type: 'crontab', value: common.replaceCronNames(expression) },
|
|
50
|
-
},
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return target.apply(thisArg, [monitorSlug, expression, monitoredCallback]);
|
|
55
|
-
},
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return target[prop];
|
|
60
|
-
},
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
exports.instrumentNodeSchedule = instrumentNodeSchedule;
|
|
65
|
-
//# sourceMappingURL=node-schedule.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"node-schedule.js","sources":["../../../src/cron/node-schedule.ts"],"sourcesContent":["import { withMonitor } from '@sentry/core';\nimport { replaceCronNames } from './common';\n\nexport interface NodeSchedule {\n scheduleJob(\n nameOrExpression: string | Date | object,\n expressionOrCallback: string | Date | object | (() => void),\n callback?: () => void,\n ): unknown;\n}\n\n/**\n * Instruments the `node-schedule` library to send a check-in event to Sentry for each job execution.\n *\n * ```ts\n * import * as Sentry from '@sentry/node';\n * import * as schedule from 'node-schedule';\n *\n * const scheduleWithCheckIn = Sentry.cron.instrumentNodeSchedule(schedule);\n *\n * const job = scheduleWithCheckIn.scheduleJob('my-cron-job', '* * * * *', () => {\n * console.log('You will see this message every minute');\n * });\n * ```\n */\nexport function instrumentNodeSchedule<T>(lib: T & NodeSchedule): T {\n return new Proxy(lib, {\n get(target, prop: keyof NodeSchedule) {\n if (prop === 'scheduleJob') {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n return new Proxy(target.scheduleJob, {\n apply(target, thisArg, argArray: Parameters<NodeSchedule['scheduleJob']>) {\n const [nameOrExpression, expressionOrCallback, callback] = argArray;\n\n if (\n typeof nameOrExpression !== 'string' ||\n typeof expressionOrCallback !== 'string' ||\n typeof callback !== 'function'\n ) {\n throw new Error(\n \"Automatic instrumentation of 'node-schedule' requires the first parameter of 'scheduleJob' to be a job name string and the second parameter to be a crontab string\",\n );\n }\n\n const monitorSlug = nameOrExpression;\n const expression = expressionOrCallback;\n\n async function monitoredCallback(): Promise<void> {\n return withMonitor(\n monitorSlug,\n async () => {\n await callback?.();\n },\n {\n schedule: { type: 'crontab', value: replaceCronNames(expression) },\n },\n );\n }\n\n return target.apply(thisArg, [monitorSlug, expression, monitoredCallback]);\n },\n });\n }\n\n return target[prop];\n },\n });\n}\n"],"names":["withMonitor","replaceCronNames"],"mappings":";;;;;AAWA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,sBAAsB,CAAI,GAAG,EAAuB;AACpE,EAAE,OAAO,IAAI,KAAK,CAAC,GAAG,EAAE;AACxB,IAAI,GAAG,CAAC,MAAM,EAAE,IAAI,EAAsB;AAC1C,MAAM,IAAI,IAAK,KAAI,aAAa,EAAE;AAClC;AACA,QAAQ,OAAO,IAAI,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE;AAC7C,UAAU,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAA2C;AACpF,YAAY,MAAM,CAAC,gBAAgB,EAAE,oBAAoB,EAAE,QAAQ,CAAE,GAAE,QAAQ;;AAE/E,YAAY;AACZ,cAAc,OAAO,gBAAiB,KAAI,QAAS;AACnD,cAAc,OAAO,oBAAqB,KAAI,QAAS;AACvD,cAAc,OAAO,aAAa;AAClC,cAAc;AACd,cAAc,MAAM,IAAI,KAAK;AAC7B,gBAAgB,oKAAoK;AACpL,eAAe;AACf;;AAEA,YAAY,MAAM,WAAY,GAAE,gBAAgB;AAChD,YAAY,MAAM,UAAW,GAAE,oBAAoB;;AAEnD,YAAY,eAAe,iBAAiB,GAAkB;AAC9D,cAAc,OAAOA,gBAAW;AAChC,gBAAgB,WAAW;AAC3B,gBAAgB,YAAY;AAC5B,kBAAkB,MAAM,QAAQ,IAAI;AACpC,iBAAiB;AACjB,gBAAgB;AAChB,kBAAkB,QAAQ,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAEC,uBAAgB,CAAC,UAAU,GAAG;AACpF,iBAAiB;AACjB,eAAe;AACf;;AAEA,YAAY,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,iBAAiB,CAAC,CAAC;AACtF,WAAW;AACX,SAAS,CAAC;AACV;;AAEA,MAAM,OAAO,MAAM,CAAC,IAAI,CAAC;AACzB,KAAK;AACL,GAAG,CAAC;AACJ;;;;"}
|
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
|
|
3
|
-
const node_util = require('node:util');
|
|
4
|
-
const node_worker_threads = require('node:worker_threads');
|
|
5
|
-
const core = require('@sentry/core');
|
|
6
|
-
const nodeVersion = require('../../nodeVersion.js');
|
|
7
|
-
const debug = require('../../utils/debug.js');
|
|
8
|
-
|
|
9
|
-
const { isPromise } = node_util.types;
|
|
10
|
-
|
|
11
|
-
// This string is a placeholder that gets overwritten with the worker code.
|
|
12
|
-
const base64WorkerScript = 'LyohIEBzZW50cnkvbm9kZSA5LjMzLjAgKDcwZTQyNWYpIHwgaHR0cHM6Ly9naXRodWIuY29tL2dldHNlbnRyeS9zZW50cnktamF2YXNjcmlwdCAqLwppbXBvcnR7U2Vzc2lvbiBhcyB0fWZyb20ibm9kZTppbnNwZWN0b3IiO2ltcG9ydHt3b3JrZXJEYXRhIGFzIG4scGFyZW50UG9ydCBhcyBlfWZyb20ibm9kZTp3b3JrZXJfdGhyZWFkcyI7aW1wb3J0e3Bvc2l4IGFzIHIsc2VwIGFzIG99ZnJvbSJub2RlOnBhdGgiO2ltcG9ydCphcyBzIGZyb20ibm9kZTpodHRwIjtpbXBvcnQqYXMgaSBmcm9tIm5vZGU6aHR0cHMiO2ltcG9ydHtSZWFkYWJsZSBhcyBjfWZyb20ibm9kZTpzdHJlYW0iO2ltcG9ydHtjcmVhdGVHemlwIGFzIHV9ZnJvbSJub2RlOnpsaWIiO2ltcG9ydCphcyBhIGZyb20ibm9kZTpuZXQiO2ltcG9ydCphcyBmIGZyb20ibm9kZTp0bHMiO2NvbnN0IGg9InVuZGVmaW5lZCI9PXR5cGVvZiBfX1NFTlRSWV9ERUJVR19ffHxfX1NFTlRSWV9ERUJVR19fLHA9Z2xvYmFsVGhpcyxsPSI5LjMzLjAiO2Z1bmN0aW9uIGQoKXtyZXR1cm4gbShwKSxwfWZ1bmN0aW9uIG0odCl7Y29uc3Qgbj10Ll9fU0VOVFJZX189dC5fX1NFTlRSWV9ffHx7fTtyZXR1cm4gbi52ZXJzaW9uPW4udmVyc2lvbnx8bCxuW2xdPW5bbF18fHt9fWZ1bmN0aW9uIGcodCxuLGU9cCl7Y29uc3Qgcj1lLl9fU0VOVFJZX189ZS5fX1NFTlRSWV9ffHx7fSxvPXJbbF09cltsXXx8e307cmV0dXJuIG9bdF18fChvW3RdPW4oKSl9Y29uc3QgeT1bImRlYnVnIiwiaW5mbyIsIndhcm4iLCJlcnJvciIsImxvZyIsImFzc2VydCIsInRyYWNlIl0sYj17fTtmdW5jdGlvbiB2KHQpe2lmKCEoImNvbnNvbGUiaW4gcCkpcmV0dXJuIHQoKTtjb25zdCBuPXAuY29uc29sZSxlPXt9LHI9T2JqZWN0LmtleXMoYik7ci5mb3JFYWNoKCh0PT57Y29uc3Qgcj1iW3RdO2VbdF09blt0XSxuW3RdPXJ9KSk7dHJ5e3JldHVybiB0KCl9ZmluYWxseXtyLmZvckVhY2goKHQ9PntuW3RdPWVbdF19KSl9fWNvbnN0IF89ZygibG9nZ2VyIiwoZnVuY3Rpb24oKXtsZXQgdD0hMTtjb25zdCBuPXtlbmFibGU6KCk9Pnt0PSEwfSxkaXNhYmxlOigpPT57dD0hMX0saXNFbmFibGVkOigpPT50fTtyZXR1cm4gaD95LmZvckVhY2goKGU9PntuW2VdPSguLi5uKT0+e3QmJnYoKCgpPT57cC5jb25zb2xlW2VdKGBTZW50cnkgTG9nZ2VyIFske2V9XTpgLC4uLm4pfSkpfX0pKTp5LmZvckVhY2goKHQ9PntuW3RdPSgpPT57fX0pKSxufSkpLHc9NTAsUz0iPyIsJD0vY2FwdHVyZU1lc3NhZ2V8Y2FwdHVyZUV4Y2VwdGlvbi87ZnVuY3Rpb24gRSh0KXtyZXR1cm4gdFt0Lmxlbmd0aC0xXXx8e319Y29uc3QgeD0iPGFub255bW91cz4iO2NvbnN0IE49T2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztmdW5jdGlvbiBDKHQsbil7cmV0dXJuIE4uY2FsbCh0KT09PWBbb2JqZWN0ICR7bn1dYH1mdW5jdGlvbiBUKHQpe3JldHVybiBDKHQsIlN0cmluZyIpfWZ1bmN0aW9uIGsodCl7cmV0dXJuIEModCwiT2JqZWN0Iil9ZnVuY3Rpb24gaih0KXtyZXR1cm4gQm9vbGVhbih0Py50aGVuJiYiZnVuY3Rpb24iPT10eXBlb2YgdC50aGVuKX1mdW5jdGlvbiBSKHQsbil7dHJ5e3JldHVybiB0IGluc3RhbmNlb2Ygbn1jYXRjaCh0KXtyZXR1cm4hMX19Y29uc3QgST1wLE89ODA7ZnVuY3Rpb24gRCh0LG4pe2NvbnN0IGU9dCxyPVtdO2lmKCFlPy50YWdOYW1lKXJldHVybiIiO2lmKEkuSFRNTEVsZW1lbnQmJmUgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCYmZS5kYXRhc2V0KXtpZihlLmRhdGFzZXQuc2VudHJ5Q29tcG9uZW50KXJldHVybiBlLmRhdGFzZXQuc2VudHJ5Q29tcG9uZW50O2lmKGUuZGF0YXNldC5zZW50cnlFbGVtZW50KXJldHVybiBlLmRhdGFzZXQuc2VudHJ5RWxlbWVudH1yLnB1c2goZS50YWdOYW1lLnRvTG93ZXJDYXNlKCkpO2NvbnN0IG89bj8ubGVuZ3RoP24uZmlsdGVyKCh0PT5lLmdldEF0dHJpYnV0ZSh0KSkpLm1hcCgodD0+W3QsZS5nZXRBdHRyaWJ1dGUodCldKSk6bnVsbDtpZihvPy5sZW5ndGgpby5mb3JFYWNoKCh0PT57ci5wdXNoKGBbJHt0WzBdfT0iJHt0WzFdfSJdYCl9KSk7ZWxzZXtlLmlkJiZyLnB1c2goYCMke2UuaWR9YCk7Y29uc3QgdD1lLmNsYXNzTmFtZTtpZih0JiZUKHQpKXtjb25zdCBuPXQuc3BsaXQoL1xzKy8pO2Zvcihjb25zdCB0IG9mIG4pci5wdXNoKGAuJHt0fWApfX1jb25zdCBzPVsiYXJpYS1sYWJlbCIsInR5cGUiLCJuYW1lIiwidGl0bGUiLCJhbHQiXTtmb3IoY29uc3QgdCBvZiBzKXtjb25zdCBuPWUuZ2V0QXR0cmlidXRlKHQpO24mJnIucHVzaChgWyR7dH09IiR7bn0iXWApfXJldHVybiByLmpvaW4oIiIpfWZ1bmN0aW9uIEEodCxuPTApe3JldHVybiJzdHJpbmciIT10eXBlb2YgdHx8MD09PW58fHQubGVuZ3RoPD1uP3Q6YCR7dC5zbGljZSgwLG4pfS4uLmB9ZnVuY3Rpb24gUCh0KXtpZihmdW5jdGlvbih0KXtzd2l0Y2goTi5jYWxsKHQpKXtjYXNlIltvYmplY3QgRXJyb3JdIjpjYXNlIltvYmplY3QgRXhjZXB0aW9uXSI6Y2FzZSJbb2JqZWN0IERPTUV4Y2VwdGlvbl0iOmNhc2UiW29iamVjdCBXZWJBc3NlbWJseS5FeGNlcHRpb25dIjpyZXR1cm4hMDtkZWZhdWx0OnJldHVybiBSKHQsRXJyb3IpfX0odCkpcmV0dXJue21lc3NhZ2U6dC5tZXNzYWdlLG5hbWU6dC5uYW1lLHN0YWNrOnQuc3RhY2ssLi4uTSh0KX07aWYobj10LCJ1bmRlZmluZWQiIT10eXBlb2YgRXZlbnQmJlIobixFdmVudCkpe2NvbnN0IG49e3R5cGU6dC50eXBlLHRhcmdldDpVKHQudGFyZ2V0KSxjdXJyZW50VGFyZ2V0OlUodC5jdXJyZW50VGFyZ2V0KSwuLi5NKHQpfTtyZXR1cm4idW5kZWZpbmVkIiE9dHlwZW9mIEN1c3RvbUV2ZW50JiZSKHQsQ3VzdG9tRXZlbnQpJiYobi5kZXRhaWw9dC5kZXRhaWwpLG59cmV0dXJuIHQ7dmFyIG59ZnVuY3Rpb24gVSh0KXt0cnl7cmV0dXJuIG49dCwidW5kZWZpbmVkIiE9dHlwZW9mIEVsZW1lbnQmJlIobixFbGVtZW50KT9mdW5jdGlvbih0LG49e30pe2lmKCF0KXJldHVybiI8dW5rbm93bj4iO3RyeXtsZXQgZT10O2NvbnN0IHI9NSxvPVtdO2xldCBzPTAsaT0wO2NvbnN0IGM9IiA+ICIsdT1jLmxlbmd0aDtsZXQgYTtjb25zdCBmPUFycmF5LmlzQXJyYXkobik/bjpuLmtleUF0dHJzLGg9IUFycmF5LmlzQXJyYXkobikmJm4ubWF4U3RyaW5nTGVuZ3RofHxPO2Zvcig7ZSYmcysrPHImJihhPUQoZSxmKSwhKCJodG1sIj09PWF8fHM+MSYmaStvLmxlbmd0aCp1K2EubGVuZ3RoPj1oKSk7KW8ucHVzaChhKSxpKz1hLmxlbmd0aCxlPWUucGFyZW50Tm9kZTtyZXR1cm4gby5yZXZlcnNlKCkuam9pbihjKX1jYXRjaCh0KXtyZXR1cm4iPHVua25vd24+In19KHQpOk9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh0KX1jYXRjaCh0KXtyZXR1cm4iPHVua25vd24+In12YXIgbn1mdW5jdGlvbiBNKHQpe2lmKCJvYmplY3QiPT10eXBlb2YgdCYmbnVsbCE9PXQpe2NvbnN0IG49e307Zm9yKGNvbnN0IGUgaW4gdClPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodCxlKSYmKG5bZV09dFtlXSk7cmV0dXJuIG59cmV0dXJue319ZnVuY3Rpb24gTCh0PWZ1bmN0aW9uKCl7Y29uc3QgdD1wO3JldHVybiB0LmNyeXB0b3x8dC5tc0NyeXB0b30oKSl7bGV0IG49KCk9PjE2Kk1hdGgucmFuZG9tKCk7dHJ5e2lmKHQ/LnJhbmRvbVVVSUQpcmV0dXJuIHQucmFuZG9tVVVJRCgpLnJlcGxhY2UoLy0vZywiIik7dD8uZ2V0UmFuZG9tVmFsdWVzJiYobj0oKT0+e2NvbnN0IG49bmV3IFVpbnQ4QXJyYXkoMSk7cmV0dXJuIHQuZ2V0UmFuZG9tVmFsdWVzKG4pLG5bMF19KX1jYXRjaCh0KXt9cmV0dXJuKFsxZTddKzFlMys0ZTMrOGUzKzFlMTEpLnJlcGxhY2UoL1swMThdL2csKHQ9Pih0XigxNSZuKCkpPj50LzQpLnRvU3RyaW5nKDE2KSkpfWNvbnN0IEI9MWUzO2Z1bmN0aW9uIEcoKXtyZXR1cm4gRGF0ZS5ub3coKS9CfWNvbnN0IEo9ZnVuY3Rpb24oKXtjb25zdHtwZXJmb3JtYW5jZTp0fT1wO2lmKCF0Py5ub3cpcmV0dXJuIEc7Y29uc3Qgbj1EYXRlLm5vdygpLXQubm93KCksZT1udWxsPT10LnRpbWVPcmlnaW4/bjp0LnRpbWVPcmlnaW47cmV0dXJuKCk9PihlK3Qubm93KCkpL0J9KCk7ZnVuY3Rpb24geih0KXtjb25zdCBuPUooKSxlPXtzaWQ6TCgpLGluaXQ6ITAsdGltZXN0YW1wOm4sc3RhcnRlZDpuLGR1cmF0aW9uOjAsc3RhdHVzOiJvayIsZXJyb3JzOjAsaWdub3JlRHVyYXRpb246ITEsdG9KU09OOigpPT5mdW5jdGlvbih0KXtyZXR1cm57c2lkOmAke3Quc2lkfWAsaW5pdDp0LmluaXQsc3RhcnRlZDpuZXcgRGF0ZSgxZTMqdC5zdGFydGVkKS50b0lTT1N0cmluZygpLHRpbWVzdGFtcDpuZXcgRGF0ZSgxZTMqdC50aW1lc3RhbXApLnRvSVNPU3RyaW5nKCksc3RhdHVzOnQuc3RhdHVzLGVycm9yczp0LmVycm9ycyxkaWQ6Im51bWJlciI9PXR5cGVvZiB0LmRpZHx8InN0cmluZyI9PXR5cGVvZiB0LmRpZD9gJHt0LmRpZH1gOnZvaWQgMCxkdXJhdGlvbjp0LmR1cmF0aW9uLGFibm9ybWFsX21lY2hhbmlzbTp0LmFibm9ybWFsX21lY2hhbmlzbSxhdHRyczp7cmVsZWFzZTp0LnJlbGVhc2UsZW52aXJvbm1lbnQ6dC5lbnZpcm9ubWVudCxpcF9hZGRyZXNzOnQuaXBBZGRyZXNzLHVzZXJfYWdlbnQ6dC51c2VyQWdlbnR9fX0oZSl9O3JldHVybiB0JiZIKGUsdCksZX1mdW5jdGlvbiBIKHQsbj17fSl7aWYobi51c2VyJiYoIXQuaXBBZGRyZXNzJiZuLnVzZXIuaXBfYWRkcmVzcyYmKHQuaXBBZGRyZXNzPW4udXNlci5pcF9hZGRyZXNzKSx0LmRpZHx8bi5kaWR8fCh0LmRpZD1uLnVzZXIuaWR8fG4udXNlci5lbWFpbHx8bi51c2VyLnVzZXJuYW1lKSksdC50aW1lc3RhbXA9bi50aW1lc3RhbXB8fEooKSxuLmFibm9ybWFsX21lY2hhbmlzbSYmKHQuYWJub3JtYWxfbWVjaGFuaXNtPW4uYWJub3JtYWxfbWVjaGFuaXNtKSxuLmlnbm9yZUR1cmF0aW9uJiYodC5pZ25vcmVEdXJhdGlvbj1uLmlnbm9yZUR1cmF0aW9uKSxuLnNpZCYmKHQuc2lkPTMyPT09bi5zaWQubGVuZ3RoP24uc2lkOkwoKSksdm9pZCAwIT09bi5pbml0JiYodC5pbml0PW4uaW5pdCksIXQuZGlkJiZuLmRpZCYmKHQuZGlkPWAke24uZGlkfWApLCJudW1iZXIiPT10eXBlb2Ygbi5zdGFydGVkJiYodC5zdGFydGVkPW4uc3RhcnRlZCksdC5pZ25vcmVEdXJhdGlvbil0LmR1cmF0aW9uPXZvaWQgMDtlbHNlIGlmKCJudW1iZXIiPT10eXBlb2Ygbi5kdXJhdGlvbil0LmR1cmF0aW9uPW4uZHVyYXRpb247ZWxzZXtjb25zdCBuPXQudGltZXN0YW1wLXQuc3RhcnRlZDt0LmR1cmF0aW9uPW4+PTA/bjowfW4ucmVsZWFzZSYmKHQucmVsZWFzZT1uLnJlbGVhc2UpLG4uZW52aXJvbm1lbnQmJih0LmVudmlyb25tZW50PW4uZW52aXJvbm1lbnQpLCF0LmlwQWRkcmVzcyYmbi5pcEFkZHJlc3MmJih0LmlwQWRkcmVzcz1uLmlwQWRkcmVzcyksIXQudXNlckFnZW50JiZuLnVzZXJBZ2VudCYmKHQudXNlckFnZW50PW4udXNlckFnZW50KSwibnVtYmVyIj09dHlwZW9mIG4uZXJyb3JzJiYodC5lcnJvcnM9bi5lcnJvcnMpLG4uc3RhdHVzJiYodC5zdGF0dXM9bi5zdGF0dXMpfWZ1bmN0aW9uIEYodCxuLGU9Mil7aWYoIW58fCJvYmplY3QiIT10eXBlb2Ygbnx8ZTw9MClyZXR1cm4gbjtpZih0JiYwPT09T2JqZWN0LmtleXMobikubGVuZ3RoKXJldHVybiB0O2NvbnN0IHI9ey4uLnR9O2Zvcihjb25zdCB0IGluIG4pT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG4sdCkmJihyW3RdPUYoclt0XSxuW3RdLGUtMSkpO3JldHVybiByfWZ1bmN0aW9uIFcoKXtyZXR1cm4gTCgpfWZ1bmN0aW9uIFkoKXtyZXR1cm4gTCgpLnN1YnN0cmluZygxNil9Y29uc3QgSz0iX3NlbnRyeVNwYW4iO2Z1bmN0aW9uIFYodCxuKXtuP2Z1bmN0aW9uKHQsbixlKXt0cnl7T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsbix7dmFsdWU6ZSx3cml0YWJsZTohMCxjb25maWd1cmFibGU6ITB9KX1jYXRjaChlKXtoJiZfLmxvZyhgRmFpbGVkIHRvIGFkZCBub24tZW51bWVyYWJsZSBwcm9wZXJ0eSAiJHtufSIgdG8gb2JqZWN0YCx0KX19KHQsSyxuKTpkZWxldGUgdFtLXX1mdW5jdGlvbiBaKHQpe3JldHVybiB0W0tdfWNsYXNzIHF7Y29uc3RydWN0b3IoKXt0aGlzLnQ9ITEsdGhpcy5vPVtdLHRoaXMuaT1bXSx0aGlzLnU9W10sdGhpcy5oPVtdLHRoaXMucD17fSx0aGlzLmw9e30sdGhpcy5tPXt9LHRoaXMudj17fSx0aGlzLl89e30sdGhpcy5TPXt0cmFjZUlkOlcoKSxzYW1wbGVSYW5kOk1hdGgucmFuZG9tKCl9fWNsb25lKCl7Y29uc3QgdD1uZXcgcTtyZXR1cm4gdC51PVsuLi50aGlzLnVdLHQubD17Li4udGhpcy5sfSx0Lm09ey4uLnRoaXMubX0sdC52PXsuLi50aGlzLnZ9LHRoaXMudi5mbGFncyYmKHQudi5mbGFncz17dmFsdWVzOlsuLi50aGlzLnYuZmxhZ3MudmFsdWVzXX0pLHQucD10aGlzLnAsdC5OPXRoaXMuTix0LkM9dGhpcy5DLHQuVD10aGlzLlQsdC5rPXRoaXMuayx0Lmk9Wy4uLnRoaXMuaV0sdC5oPVsuLi50aGlzLmhdLHQuXz17Li4udGhpcy5ffSx0LlM9ey4uLnRoaXMuU30sdC5qPXRoaXMuaix0LlI9dGhpcy5SLFYodCxaKHRoaXMpKSx0fXNldENsaWVudCh0KXt0aGlzLmo9dH1zZXRMYXN0RXZlbnRJZCh0KXt0aGlzLlI9dH1nZXRDbGllbnQoKXtyZXR1cm4gdGhpcy5qfWxhc3RFdmVudElkKCl7cmV0dXJuIHRoaXMuUn1hZGRTY29wZUxpc3RlbmVyKHQpe3RoaXMuby5wdXNoKHQpfWFkZEV2ZW50UHJvY2Vzc29yKHQpe3JldHVybiB0aGlzLmkucHVzaCh0KSx0aGlzfXNldFVzZXIodCl7cmV0dXJuIHRoaXMucD10fHx7ZW1haWw6dm9pZCAwLGlkOnZvaWQgMCxpcF9hZGRyZXNzOnZvaWQgMCx1c2VybmFtZTp2b2lkIDB9LHRoaXMuQyYmSCh0aGlzLkMse3VzZXI6dH0pLHRoaXMuSSgpLHRoaXN9Z2V0VXNlcigpe3JldHVybiB0aGlzLnB9c2V0VGFncyh0KXtyZXR1cm4gdGhpcy5sPXsuLi50aGlzLmwsLi4udH0sdGhpcy5JKCksdGhpc31zZXRUYWcodCxuKXtyZXR1cm4gdGhpcy5sPXsuLi50aGlzLmwsW3RdOm59LHRoaXMuSSgpLHRoaXN9c2V0RXh0cmFzKHQpe3JldHVybiB0aGlzLm09ey4uLnRoaXMubSwuLi50fSx0aGlzLkkoKSx0aGlzfXNldEV4dHJhKHQsbil7cmV0dXJuIHRoaXMubT17Li4udGhpcy5tLFt0XTpufSx0aGlzLkkoKSx0aGlzfXNldEZpbmdlcnByaW50KHQpe3JldHVybiB0aGlzLms9dCx0aGlzLkkoKSx0aGlzfXNldExldmVsKHQpe3JldHVybiB0aGlzLk49dCx0aGlzLkkoKSx0aGlzfXNldFRyYW5zYWN0aW9uTmFtZSh0KXtyZXR1cm4gdGhpcy5UPXQsdGhpcy5JKCksdGhpc31zZXRDb250ZXh0KHQsbil7cmV0dXJuIG51bGw9PT1uP2RlbGV0ZSB0aGlzLnZbdF06dGhpcy52W3RdPW4sdGhpcy5JKCksdGhpc31zZXRTZXNzaW9uKHQpe3JldHVybiB0P3RoaXMuQz10OmRlbGV0ZSB0aGlzLkMsdGhpcy5JKCksdGhpc31nZXRTZXNzaW9uKCl7cmV0dXJuIHRoaXMuQ311cGRhdGUodCl7aWYoIXQpcmV0dXJuIHRoaXM7Y29uc3Qgbj0iZnVuY3Rpb24iPT10eXBlb2YgdD90KHRoaXMpOnQsZT1uIGluc3RhbmNlb2YgcT9uLmdldFNjb3BlRGF0YSgpOmsobik/dDp2b2lkIDAse3RhZ3M6cixleHRyYTpvLHVzZXI6cyxjb250ZXh0czppLGxldmVsOmMsZmluZ2VycHJpbnQ6dT1bXSxwcm9wYWdhdGlvbkNvbnRleHQ6YX09ZXx8e307cmV0dXJuIHRoaXMubD17Li4udGhpcy5sLC4uLnJ9LHRoaXMubT17Li4udGhpcy5tLC4uLm99LHRoaXMudj17Li4udGhpcy52LC4uLml9LHMmJk9iamVjdC5rZXlzKHMpLmxlbmd0aCYmKHRoaXMucD1zKSxjJiYodGhpcy5OPWMpLHUubGVuZ3RoJiYodGhpcy5rPXUpLGEmJih0aGlzLlM9YSksdGhpc31jbGVhcigpe3JldHVybiB0aGlzLnU9W10sdGhpcy5sPXt9LHRoaXMubT17fSx0aGlzLnA9e30sdGhpcy52PXt9LHRoaXMuTj12b2lkIDAsdGhpcy5UPXZvaWQgMCx0aGlzLms9dm9pZCAwLHRoaXMuQz12b2lkIDAsVih0aGlzLHZvaWQgMCksdGhpcy5oPVtdLHRoaXMuc2V0UHJvcGFnYXRpb25Db250ZXh0KHt0cmFjZUlkOlcoKSxzYW1wbGVSYW5kOk1hdGgucmFuZG9tKCl9KSx0aGlzLkkoKSx0aGlzfWFkZEJyZWFkY3J1bWIodCxuKXtjb25zdCBlPSJudW1iZXIiPT10eXBlb2Ygbj9uOjEwMDtpZihlPD0wKXJldHVybiB0aGlzO2NvbnN0IHI9e3RpbWVzdGFtcDpHKCksLi4udCxtZXNzYWdlOnQubWVzc2FnZT9BKHQubWVzc2FnZSwyMDQ4KTp0Lm1lc3NhZ2V9O3JldHVybiB0aGlzLnUucHVzaChyKSx0aGlzLnUubGVuZ3RoPmUmJih0aGlzLnU9dGhpcy51LnNsaWNlKC1lKSx0aGlzLmo/LnJlY29yZERyb3BwZWRFdmVudCgiYnVmZmVyX292ZXJmbG93IiwibG9nX2l0ZW0iKSksdGhpcy5JKCksdGhpc31nZXRMYXN0QnJlYWRjcnVtYigpe3JldHVybiB0aGlzLnVbdGhpcy51Lmxlbmd0aC0xXX1jbGVhckJyZWFkY3J1bWJzKCl7cmV0dXJuIHRoaXMudT1bXSx0aGlzLkkoKSx0aGlzfWFkZEF0dGFjaG1lbnQodCl7cmV0dXJuIHRoaXMuaC5wdXNoKHQpLHRoaXN9Y2xlYXJBdHRhY2htZW50cygpe3JldHVybiB0aGlzLmg9W10sdGhpc31nZXRTY29wZURhdGEoKXtyZXR1cm57YnJlYWRjcnVtYnM6dGhpcy51LGF0dGFjaG1lbnRzOnRoaXMuaCxjb250ZXh0czp0aGlzLnYsdGFnczp0aGlzLmwsZXh0cmE6dGhpcy5tLHVzZXI6dGhpcy5wLGxldmVsOnRoaXMuTixmaW5nZXJwcmludDp0aGlzLmt8fFtdLGV2ZW50UHJvY2Vzc29yczp0aGlzLmkscHJvcGFnYXRpb25Db250ZXh0OnRoaXMuUyxzZGtQcm9jZXNzaW5nTWV0YWRhdGE6dGhpcy5fLHRyYW5zYWN0aW9uTmFtZTp0aGlzLlQsc3BhbjpaKHRoaXMpfX1zZXRTREtQcm9jZXNzaW5nTWV0YWRhdGEodCl7cmV0dXJuIHRoaXMuXz1GKHRoaXMuXyx0LDIpLHRoaXN9c2V0UHJvcGFnYXRpb25Db250ZXh0KHQpe3JldHVybiB0aGlzLlM9dCx0aGlzfWdldFByb3BhZ2F0aW9uQ29udGV4dCgpe3JldHVybiB0aGlzLlN9Y2FwdHVyZUV4Y2VwdGlvbih0LG4pe2NvbnN0IGU9bj8uZXZlbnRfaWR8fEwoKTtpZighdGhpcy5qKXJldHVybiBfLndhcm4oIk5vIGNsaWVudCBjb25maWd1cmVkIG9uIHNjb3BlIC0gd2lsbCBub3QgY2FwdHVyZSBleGNlcHRpb24hIiksZTtjb25zdCByPW5ldyBFcnJvcigiU2VudHJ5IHN5bnRoZXRpY0V4Y2VwdGlvbiIpO3JldHVybiB0aGlzLmouY2FwdHVyZUV4Y2VwdGlvbih0LHtvcmlnaW5hbEV4Y2VwdGlvbjp0LHN5bnRoZXRpY0V4Y2VwdGlvbjpyLC4uLm4sZXZlbnRfaWQ6ZX0sdGhpcyksZX1jYXB0dXJlTWVzc2FnZSh0LG4sZSl7Y29uc3Qgcj1lPy5ldmVudF9pZHx8TCgpO2lmKCF0aGlzLmopcmV0dXJuIF8ud2FybigiTm8gY2xpZW50IGNvbmZpZ3VyZWQgb24gc2NvcGUgLSB3aWxsIG5vdCBjYXB0dXJlIG1lc3NhZ2UhIikscjtjb25zdCBvPW5ldyBFcnJvcih0KTtyZXR1cm4gdGhpcy5qLmNhcHR1cmVNZXNzYWdlKHQsbix7b3JpZ2luYWxFeGNlcHRpb246dCxzeW50aGV0aWNFeGNlcHRpb246bywuLi5lLGV2ZW50X2lkOnJ9LHRoaXMpLHJ9Y2FwdHVyZUV2ZW50KHQsbil7Y29uc3QgZT1uPy5ldmVudF9pZHx8TCgpO3JldHVybiB0aGlzLmo/KHRoaXMuai5jYXB0dXJlRXZlbnQodCx7Li4ubixldmVudF9pZDplfSx0aGlzKSxlKTooXy53YXJuKCJObyBjbGllbnQgY29uZmlndXJlZCBvbiBzY29wZSAtIHdpbGwgbm90IGNhcHR1cmUgZXZlbnQhIiksZSl9SSgpe3RoaXMudHx8KHRoaXMudD0hMCx0aGlzLm8uZm9yRWFjaCgodD0+e3QodGhpcyl9KSksdGhpcy50PSExKX19Y2xhc3MgUXtjb25zdHJ1Y3Rvcih0LG4pe2xldCBlLHI7ZT10fHxuZXcgcSxyPW58fG5ldyBxLHRoaXMuTz1be3Njb3BlOmV9XSx0aGlzLkQ9cn13aXRoU2NvcGUodCl7Y29uc3Qgbj10aGlzLkEoKTtsZXQgZTt0cnl7ZT10KG4pfWNhdGNoKHQpe3Rocm93IHRoaXMuUCgpLHR9cmV0dXJuIGooZSk/ZS50aGVuKCh0PT4odGhpcy5QKCksdCkpLCh0PT57dGhyb3cgdGhpcy5QKCksdH0pKToodGhpcy5QKCksZSl9Z2V0Q2xpZW50KCl7cmV0dXJuIHRoaXMuZ2V0U3RhY2tUb3AoKS5jbGllbnR9Z2V0U2NvcGUoKXtyZXR1cm4gdGhpcy5nZXRTdGFja1RvcCgpLnNjb3BlfWdldElzb2xhdGlvblNjb3BlKCl7cmV0dXJuIHRoaXMuRH1nZXRTdGFja1RvcCgpe3JldHVybiB0aGlzLk9bdGhpcy5PLmxlbmd0aC0xXX1BKCl7Y29uc3QgdD10aGlzLmdldFNjb3BlKCkuY2xvbmUoKTtyZXR1cm4gdGhpcy5PLnB1c2goe2NsaWVudDp0aGlzLmdldENsaWVudCgpLHNjb3BlOnR9KSx0fVAoKXtyZXR1cm4hKHRoaXMuTy5sZW5ndGg8PTEpJiYhIXRoaXMuTy5wb3AoKX19ZnVuY3Rpb24gWCgpe2NvbnN0IHQ9bShkKCkpO3JldHVybiB0LnN0YWNrPXQuc3RhY2t8fG5ldyBRKGcoImRlZmF1bHRDdXJyZW50U2NvcGUiLCgoKT0+bmV3IHEpKSxnKCJkZWZhdWx0SXNvbGF0aW9uU2NvcGUiLCgoKT0+bmV3IHEpKSl9ZnVuY3Rpb24gdHQodCl7cmV0dXJuIFgoKS53aXRoU2NvcGUodCl9ZnVuY3Rpb24gbnQodCxuKXtjb25zdCBlPVgoKTtyZXR1cm4gZS53aXRoU2NvcGUoKCgpPT4oZS5nZXRTdGFja1RvcCgpLnNjb3BlPXQsbih0KSkpKX1mdW5jdGlvbiBldCh0KXtyZXR1cm4gWCgpLndpdGhTY29wZSgoKCk9PnQoWCgpLmdldElzb2xhdGlvblNjb3BlKCkpKSl9ZnVuY3Rpb24gcnQodCl7Y29uc3Qgbj1tKHQpO3JldHVybiBuLmFjcz9uLmFjczp7d2l0aElzb2xhdGlvblNjb3BlOmV0LHdpdGhTY29wZTp0dCx3aXRoU2V0U2NvcGU6bnQsd2l0aFNldElzb2xhdGlvblNjb3BlOih0LG4pPT5ldChuKSxnZXRDdXJyZW50U2NvcGU6KCk9PlgoKS5nZXRTY29wZSgpLGdldElzb2xhdGlvblNjb3BlOigpPT5YKCkuZ2V0SXNvbGF0aW9uU2NvcGUoKX19ZnVuY3Rpb24gb3QoKXtyZXR1cm4gcnQoZCgpKS5nZXRDdXJyZW50U2NvcGUoKS5nZXRDbGllbnQoKX1jb25zdCBzdD0ic2VudHJ5LnNvdXJjZSIsaXQ9InNlbnRyeS5zYW1wbGVfcmF0ZSIsY3Q9InNlbnRyeS5wcmV2aW91c190cmFjZV9zYW1wbGVfcmF0ZSIsdXQ9InNlbnRyeS5vcCIsYXQ9InNlbnRyeS5vcmlnaW4iLGZ0PTAsaHQ9MSxwdD0iX3NlbnRyeVNjb3BlIixsdD0iX3NlbnRyeUlzb2xhdGlvblNjb3BlIjtmdW5jdGlvbiBkdCh0KXtyZXR1cm57c2NvcGU6dFtwdF0saXNvbGF0aW9uU2NvcGU6dFtsdF19fWNvbnN0IG10PSJzZW50cnktIixndD0vXnNlbnRyeS0vO2Z1bmN0aW9uIHl0KHQpe2NvbnN0IG49ZnVuY3Rpb24odCl7aWYoIXR8fCFUKHQpJiYhQXJyYXkuaXNBcnJheSh0KSlyZXR1cm47aWYoQXJyYXkuaXNBcnJheSh0KSlyZXR1cm4gdC5yZWR1Y2UoKCh0LG4pPT57Y29uc3QgZT1idChuKTtyZXR1cm4gT2JqZWN0LmVudHJpZXMoZSkuZm9yRWFjaCgoKFtuLGVdKT0+e3Rbbl09ZX0pKSx0fSkse30pO3JldHVybiBidCh0KX0odCk7aWYoIW4pcmV0dXJuO2NvbnN0IGU9T2JqZWN0LmVudHJpZXMobikucmVkdWNlKCgodCxbbixlXSk9PntpZihuLm1hdGNoKGd0KSl7dFtuLnNsaWNlKG10Lmxlbmd0aCldPWV9cmV0dXJuIHR9KSx7fSk7cmV0dXJuIE9iamVjdC5rZXlzKGUpLmxlbmd0aD4wP2U6dm9pZCAwfWZ1bmN0aW9uIGJ0KHQpe3JldHVybiB0LnNwbGl0KCIsIikubWFwKCh0PT50LnNwbGl0KCI9IikubWFwKCh0PT57dHJ5e3JldHVybiBkZWNvZGVVUklDb21wb25lbnQodC50cmltKCkpfWNhdGNoe3JldHVybn19KSkpKS5yZWR1Y2UoKCh0LFtuLGVdKT0+KG4mJmUmJih0W25dPWUpLHQpKSx7fSl9Y29uc3QgdnQ9MTtmdW5jdGlvbiBfdCh0KXtjb25zdHtzcGFuSWQ6bix0cmFjZUlkOmUsaXNSZW1vdGU6cn09dC5zcGFuQ29udGV4dCgpLG89cj9uOkV0KHQpLnBhcmVudF9zcGFuX2lkLHM9ZHQodCkuc2NvcGU7cmV0dXJue3BhcmVudF9zcGFuX2lkOm8sc3Bhbl9pZDpyP3M/LmdldFByb3BhZ2F0aW9uQ29udGV4dCgpLnByb3BhZ2F0aW9uU3BhbklkfHxZKCk6bix0cmFjZV9pZDplfX1mdW5jdGlvbiB3dCh0KXtyZXR1cm4gdCYmdC5sZW5ndGg+MD90Lm1hcCgoKHtjb250ZXh0OntzcGFuSWQ6dCx0cmFjZUlkOm4sdHJhY2VGbGFnczplLC4uLnJ9LGF0dHJpYnV0ZXM6b30pPT4oe3NwYW5faWQ6dCx0cmFjZV9pZDpuLHNhbXBsZWQ6ZT09PXZ0LGF0dHJpYnV0ZXM6bywuLi5yfSkpKTp2b2lkIDB9ZnVuY3Rpb24gU3QodCl7cmV0dXJuIm51bWJlciI9PXR5cGVvZiB0PyR0KHQpOkFycmF5LmlzQXJyYXkodCk/dFswXSt0WzFdLzFlOTp0IGluc3RhbmNlb2YgRGF0ZT8kdCh0LmdldFRpbWUoKSk6SigpfWZ1bmN0aW9uICR0KHQpe3JldHVybiB0Pjk5OTk5OTk5OTk/dC8xZTM6dH1mdW5jdGlvbiBFdCh0KXtpZihmdW5jdGlvbih0KXtyZXR1cm4iZnVuY3Rpb24iPT10eXBlb2YgdC5nZXRTcGFuSlNPTn0odCkpcmV0dXJuIHQuZ2V0U3BhbkpTT04oKTtjb25zdHtzcGFuSWQ6bix0cmFjZUlkOmV9PXQuc3BhbkNvbnRleHQoKTtpZihmdW5jdGlvbih0KXtjb25zdCBuPXQ7cmV0dXJuISEobi5hdHRyaWJ1dGVzJiZuLnN0YXJ0VGltZSYmbi5uYW1lJiZuLmVuZFRpbWUmJm4uc3RhdHVzKX0odCkpe2NvbnN0e2F0dHJpYnV0ZXM6cixzdGFydFRpbWU6byxuYW1lOnMsZW5kVGltZTppLHN0YXR1czpjLGxpbmtzOnV9PXQ7cmV0dXJue3NwYW5faWQ6bix0cmFjZV9pZDplLGRhdGE6cixkZXNjcmlwdGlvbjpzLHBhcmVudF9zcGFuX2lkOiJwYXJlbnRTcGFuSWQiaW4gdD90LnBhcmVudFNwYW5JZDoicGFyZW50U3BhbkNvbnRleHQiaW4gdD90LnBhcmVudFNwYW5Db250ZXh0Py5zcGFuSWQ6dm9pZCAwLHN0YXJ0X3RpbWVzdGFtcDpTdChvKSx0aW1lc3RhbXA6U3QoaSl8fHZvaWQgMCxzdGF0dXM6eHQoYyksb3A6clt1dF0sb3JpZ2luOnJbYXRdLGxpbmtzOnd0KHUpfX1yZXR1cm57c3Bhbl9pZDpuLHRyYWNlX2lkOmUsc3RhcnRfdGltZXN0YW1wOjAsZGF0YTp7fX19ZnVuY3Rpb24geHQodCl7aWYodCYmdC5jb2RlIT09ZnQpcmV0dXJuIHQuY29kZT09PWh0PyJvayI6dC5tZXNzYWdlfHwidW5rbm93bl9lcnJvciJ9Y29uc3QgTnQ9Il9zZW50cnlSb290U3BhbiI7ZnVuY3Rpb24gQ3QodCl7cmV0dXJuIHRbTnRdfHx0fWNvbnN0IFR0PSJwcm9kdWN0aW9uIixrdD0vXm8oXGQrKVwuLztmdW5jdGlvbiBqdCh0LG49ITEpe2NvbnN0e2hvc3Q6ZSxwYXRoOnIscGFzczpvLHBvcnQ6cyxwcm9qZWN0SWQ6aSxwcm90b2NvbDpjLHB1YmxpY0tleTp1fT10O3JldHVybmAke2N9Oi8vJHt1fSR7biYmbz9gOiR7b31gOiIifUAke2V9JHtzP2A6JHtzfWA6IiJ9LyR7cj9gJHtyfS9gOnJ9JHtpfWB9Y29uc3QgUnQ9Il9mcm96ZW5Ec2MiO2Z1bmN0aW9uIEl0KHQsbil7Y29uc3QgZT1uLmdldE9wdGlvbnMoKSx7cHVibGljS2V5OnIsaG9zdDpvfT1uLmdldERzbigpfHx7fTtsZXQgcztlLm9yZ0lkP3M9U3RyaW5nKGUub3JnSWQpOm8mJihzPWZ1bmN0aW9uKHQpe2NvbnN0IG49dC5tYXRjaChrdCk7cmV0dXJuIG4/LlsxXX0obykpO2NvbnN0IGk9e2Vudmlyb25tZW50OmUuZW52aXJvbm1lbnR8fFR0LHJlbGVhc2U6ZS5yZWxlYXNlLHB1YmxpY19rZXk6cix0cmFjZV9pZDp0LG9yZ19pZDpzfTtyZXR1cm4gbi5lbWl0KCJjcmVhdGVEc2MiLGkpLGl9ZnVuY3Rpb24gT3QodCl7Y29uc3Qgbj1vdCgpO2lmKCFuKXJldHVybnt9O2NvbnN0IGU9Q3QodCkscj1FdChlKSxvPXIuZGF0YSxzPWUuc3BhbkNvbnRleHQoKS50cmFjZVN0YXRlLGk9cz8uZ2V0KCJzZW50cnkuc2FtcGxlX3JhdGUiKT8/b1tpdF0/P29bY3RdO2Z1bmN0aW9uIGModCl7cmV0dXJuIm51bWJlciIhPXR5cGVvZiBpJiYic3RyaW5nIiE9dHlwZW9mIGl8fCh0LnNhbXBsZV9yYXRlPWAke2l9YCksdH1jb25zdCB1PWVbUnRdO2lmKHUpcmV0dXJuIGModSk7Y29uc3QgYT1zPy5nZXQoInNlbnRyeS5kc2MiKSxmPWEmJnl0KGEpO2lmKGYpcmV0dXJuIGMoZik7Y29uc3QgaD1JdCh0LnNwYW5Db250ZXh0KCkudHJhY2VJZCxuKSxwPW9bc3RdLGw9ci5kZXNjcmlwdGlvbjtyZXR1cm4idXJsIiE9PXAmJmwmJihoLnRyYW5zYWN0aW9uPWwpLGZ1bmN0aW9uKHQpe2lmKCJib29sZWFuIj09dHlwZW9mIF9fU0VOVFJZX1RSQUNJTkdfXyYmIV9fU0VOVFJZX1RSQUNJTkdfXylyZXR1cm4hMTtjb25zdCBuPXR8fG90KCk/LmdldE9wdGlvbnMoKTtyZXR1cm4hKCFufHxudWxsPT1uLnRyYWNlc1NhbXBsZVJhdGUmJiFuLnRyYWNlc1NhbXBsZXIpfSgpJiYoaC5zYW1wbGVkPVN0cmluZyhmdW5jdGlvbih0KXtjb25zdHt0cmFjZUZsYWdzOm59PXQuc3BhbkNvbnRleHQoKTtyZXR1cm4gbj09PXZ0fShlKSksaC5zYW1wbGVfcmFuZD1zPy5nZXQoInNlbnRyeS5zYW1wbGVfcmFuZCIpPz9kdChlKS5zY29wZT8uZ2V0UHJvcGFnYXRpb25Db250ZXh0KCkuc2FtcGxlUmFuZC50b1N0cmluZygpKSxjKGgpLG4uZW1pdCgiY3JlYXRlRHNjIixoLGUpLGh9ZnVuY3Rpb24gRHQodCxuPTEwMCxlPTEvMCl7dHJ5e3JldHVybiBBdCgiIix0LG4sZSl9Y2F0Y2godCl7cmV0dXJue0VSUk9SOmAqKm5vbi1zZXJpYWxpemFibGUqKiAoJHt0fSlgfX19ZnVuY3Rpb24gQXQodCxuLGU9MS8wLHI9MS8wLG89ZnVuY3Rpb24oKXtjb25zdCB0PW5ldyBXZWFrU2V0O2Z1bmN0aW9uIG4obil7cmV0dXJuISF0LmhhcyhuKXx8KHQuYWRkKG4pLCExKX1mdW5jdGlvbiBlKG4pe3QuZGVsZXRlKG4pfXJldHVybltuLGVdfSgpKXtjb25zdFtzLGldPW87aWYobnVsbD09bnx8WyJib29sZWFuIiwic3RyaW5nIl0uaW5jbHVkZXModHlwZW9mIG4pfHwibnVtYmVyIj09dHlwZW9mIG4mJk51bWJlci5pc0Zpbml0ZShuKSlyZXR1cm4gbjtjb25zdCBjPWZ1bmN0aW9uKHQsbil7dHJ5e2lmKCJkb21haW4iPT09dCYmbiYmIm9iamVjdCI9PXR5cGVvZiBuJiZuLlUpcmV0dXJuIltEb21haW5dIjtpZigiZG9tYWluRW1pdHRlciI9PT10KXJldHVybiJbRG9tYWluRW1pdHRlcl0iO2lmKCJ1bmRlZmluZWQiIT10eXBlb2YgZ2xvYmFsJiZuPT09Z2xvYmFsKXJldHVybiJbR2xvYmFsXSI7aWYoInVuZGVmaW5lZCIhPXR5cGVvZiB3aW5kb3cmJm49PT13aW5kb3cpcmV0dXJuIltXaW5kb3ddIjtpZigidW5kZWZpbmVkIiE9dHlwZW9mIGRvY3VtZW50JiZuPT09ZG9jdW1lbnQpcmV0dXJuIltEb2N1bWVudF0iO2lmKCJvYmplY3QiPT10eXBlb2YoZT1uKSYmbnVsbCE9PWUmJihlLl9faXNWdWV8fGUuTSkpcmV0dXJuIltWdWVWaWV3TW9kZWxdIjtpZihmdW5jdGlvbih0KXtyZXR1cm4gayh0KSYmIm5hdGl2ZUV2ZW50ImluIHQmJiJwcmV2ZW50RGVmYXVsdCJpbiB0JiYic3RvcFByb3BhZ2F0aW9uImluIHR9KG4pKXJldHVybiJbU3ludGhldGljRXZlbnRdIjtpZigibnVtYmVyIj09dHlwZW9mIG4mJiFOdW1iZXIuaXNGaW5pdGUobikpcmV0dXJuYFske259XWA7aWYoImZ1bmN0aW9uIj09dHlwZW9mIG4pcmV0dXJuYFtGdW5jdGlvbjogJHtmdW5jdGlvbih0KXt0cnl7cmV0dXJuIHQmJiJmdW5jdGlvbiI9PXR5cGVvZiB0JiZ0Lm5hbWV8fHh9Y2F0Y2godCl7cmV0dXJuIHh9fShuKX1dYDtpZigic3ltYm9sIj09dHlwZW9mIG4pcmV0dXJuYFske1N0cmluZyhuKX1dYDtpZigiYmlnaW50Ij09dHlwZW9mIG4pcmV0dXJuYFtCaWdJbnQ6ICR7U3RyaW5nKG4pfV1gO2NvbnN0IHI9ZnVuY3Rpb24odCl7Y29uc3Qgbj1PYmplY3QuZ2V0UHJvdG90eXBlT2YodCk7cmV0dXJuIG4/LmNvbnN0cnVjdG9yP24uY29uc3RydWN0b3IubmFtZToibnVsbCBwcm90b3R5cGUifShuKTtyZXR1cm4vXkhUTUwoXHcqKUVsZW1lbnQkLy50ZXN0KHIpP2BbSFRNTEVsZW1lbnQ6ICR7cn1dYDpgW29iamVjdCAke3J9XWB9Y2F0Y2godCl7cmV0dXJuYCoqbm9uLXNlcmlhbGl6YWJsZSoqICgke3R9KWB9dmFyIGV9KHQsbik7aWYoIWMuc3RhcnRzV2l0aCgiW29iamVjdCAiKSlyZXR1cm4gYztpZihuLl9fc2VudHJ5X3NraXBfbm9ybWFsaXphdGlvbl9fKXJldHVybiBuO2NvbnN0IHU9Im51bWJlciI9PXR5cGVvZiBuLl9fc2VudHJ5X292ZXJyaWRlX25vcm1hbGl6YXRpb25fZGVwdGhfXz9uLl9fc2VudHJ5X292ZXJyaWRlX25vcm1hbGl6YXRpb25fZGVwdGhfXzplO2lmKDA9PT11KXJldHVybiBjLnJlcGxhY2UoIm9iamVjdCAiLCIiKTtpZihzKG4pKXJldHVybiJbQ2lyY3VsYXIgfl0iO2NvbnN0IGE9bjtpZihhJiYiZnVuY3Rpb24iPT10eXBlb2YgYS50b0pTT04pdHJ5e3JldHVybiBBdCgiIixhLnRvSlNPTigpLHUtMSxyLG8pfWNhdGNoKHQpe31jb25zdCBmPUFycmF5LmlzQXJyYXkobik/W106e307bGV0IGg9MDtjb25zdCBwPVAobik7Zm9yKGNvbnN0IHQgaW4gcCl7aWYoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChwLHQpKWNvbnRpbnVlO2lmKGg+PXIpe2ZbdF09IltNYXhQcm9wZXJ0aWVzIH5dIjticmVha31jb25zdCBuPXBbdF07Zlt0XT1BdCh0LG4sdS0xLHIsbyksaCsrfXJldHVybiBpKG4pLGZ9ZnVuY3Rpb24gUHQodCxuKXtjb25zdCBlPW4ucmVwbGFjZSgvXFwvZywiLyIpLnJlcGxhY2UoL1t8XFx7fSgpW1xdXiQrKj8uXS9nLCJcXCQmIik7bGV0IHI9dDt0cnl7cj1kZWNvZGVVUkkodCl9Y2F0Y2godCl7fXJldHVybiByLnJlcGxhY2UoL1xcL2csIi8iKS5yZXBsYWNlKC93ZWJwYWNrOlwvPy9nLCIiKS5yZXBsYWNlKG5ldyBSZWdFeHAoYChmaWxlOi8vKT8vKiR7ZX0vKmAsImlnIiksImFwcDovLy8iKX1mdW5jdGlvbiBVdCh0LG49W10pe3JldHVyblt0LG5dfWZ1bmN0aW9uIE10KHQsbil7Y29uc3QgZT10WzFdO2Zvcihjb25zdCB0IG9mIGUpe2lmKG4odCx0WzBdLnR5cGUpKXJldHVybiEwfXJldHVybiExfWZ1bmN0aW9uIEx0KHQpe2NvbnN0IG49bShwKTtyZXR1cm4gbi5lbmNvZGVQb2x5ZmlsbD9uLmVuY29kZVBvbHlmaWxsKHQpOihuZXcgVGV4dEVuY29kZXIpLmVuY29kZSh0KX1mdW5jdGlvbiBCdCh0KXtjb25zdFtuLGVdPXQ7bGV0IHI9SlNPTi5zdHJpbmdpZnkobik7ZnVuY3Rpb24gbyh0KXsic3RyaW5nIj09dHlwZW9mIHI/cj0ic3RyaW5nIj09dHlwZW9mIHQ/cit0OltMdChyKSx0XTpyLnB1c2goInN0cmluZyI9PXR5cGVvZiB0P0x0KHQpOnQpfWZvcihjb25zdCB0IG9mIGUpe2NvbnN0W24sZV09dDtpZihvKGBcbiR7SlNPTi5zdHJpbmdpZnkobil9XG5gKSwic3RyaW5nIj09dHlwZW9mIGV8fGUgaW5zdGFuY2VvZiBVaW50OEFycmF5KW8oZSk7ZWxzZXtsZXQgdDt0cnl7dD1KU09OLnN0cmluZ2lmeShlKX1jYXRjaChuKXt0PUpTT04uc3RyaW5naWZ5KER0KGUpKX1vKHQpfX1yZXR1cm4ic3RyaW5nIj09dHlwZW9mIHI/cjpmdW5jdGlvbih0KXtjb25zdCBuPXQucmVkdWNlKCgodCxuKT0+dCtuLmxlbmd0aCksMCksZT1uZXcgVWludDhBcnJheShuKTtsZXQgcj0wO2Zvcihjb25zdCBuIG9mIHQpZS5zZXQobixyKSxyKz1uLmxlbmd0aDtyZXR1cm4gZX0ocil9Y29uc3QgR3Q9e3Nlc3Npb246InNlc3Npb24iLHNlc3Npb25zOiJzZXNzaW9uIixhdHRhY2htZW50OiJhdHRhY2htZW50Iix0cmFuc2FjdGlvbjoidHJhbnNhY3Rpb24iLGV2ZW50OiJlcnJvciIsY2xpZW50X3JlcG9ydDoiaW50ZXJuYWwiLHVzZXJfcmVwb3J0OiJkZWZhdWx0Iixwcm9maWxlOiJwcm9maWxlIixwcm9maWxlX2NodW5rOiJwcm9maWxlIixyZXBsYXlfZXZlbnQ6InJlcGxheSIscmVwbGF5X3JlY29yZGluZzoicmVwbGF5IixjaGVja19pbjoibW9uaXRvciIsZmVlZGJhY2s6ImZlZWRiYWNrIixzcGFuOiJzcGFuIixyYXdfc2VjdXJpdHk6InNlY3VyaXR5Iixsb2c6ImxvZ19pdGVtIn07ZnVuY3Rpb24gSnQodCl7aWYoIXQ/LnNkaylyZXR1cm47Y29uc3R7bmFtZTpuLHZlcnNpb246ZX09dC5zZGs7cmV0dXJue25hbWU6bix2ZXJzaW9uOmV9fWZ1bmN0aW9uIHp0KHQsbixlLHIpe2NvbnN0IG89SnQoZSkscz10LnR5cGUmJiJyZXBsYXlfZXZlbnQiIT09dC50eXBlP3QudHlwZToiZXZlbnQiOyFmdW5jdGlvbih0LG4pe24mJih0LnNkaz10LnNka3x8e30sdC5zZGsubmFtZT10LnNkay5uYW1lfHxuLm5hbWUsdC5zZGsudmVyc2lvbj10LnNkay52ZXJzaW9ufHxuLnZlcnNpb24sdC5zZGsuaW50ZWdyYXRpb25zPVsuLi50LnNkay5pbnRlZ3JhdGlvbnN8fFtdLC4uLm4uaW50ZWdyYXRpb25zfHxbXV0sdC5zZGsucGFja2FnZXM9Wy4uLnQuc2RrLnBhY2thZ2VzfHxbXSwuLi5uLnBhY2thZ2VzfHxbXV0pfSh0LGU/LnNkayk7Y29uc3QgaT1mdW5jdGlvbih0LG4sZSxyKXtjb25zdCBvPXQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhPy5keW5hbWljU2FtcGxpbmdDb250ZXh0O3JldHVybntldmVudF9pZDp0LmV2ZW50X2lkLHNlbnRfYXQ6KG5ldyBEYXRlKS50b0lTT1N0cmluZygpLC4uLm4mJntzZGs6bn0sLi4uISFlJiZyJiZ7ZHNuOmp0KHIpfSwuLi5vJiZ7dHJhY2U6b319fSh0LG8scixuKTtkZWxldGUgdC5zZGtQcm9jZXNzaW5nTWV0YWRhdGE7cmV0dXJuIFV0KGksW1t7dHlwZTpzfSx0XV0pfWNvbnN0IEh0PSJfX1NFTlRSWV9TVVBQUkVTU19UUkFDSU5HX18iO2Z1bmN0aW9uIEZ0KHQpe2NvbnN0IG49cnQoZCgpKTtyZXR1cm4gbi5zdXBwcmVzc1RyYWNpbmc/bi5zdXBwcmVzc1RyYWNpbmcodCk6ZnVuY3Rpb24oLi4udCl7Y29uc3Qgbj1ydChkKCkpO2lmKDI9PT10Lmxlbmd0aCl7Y29uc3RbZSxyXT10O3JldHVybiBlP24ud2l0aFNldFNjb3BlKGUscik6bi53aXRoU2NvcGUocil9cmV0dXJuIG4ud2l0aFNjb3BlKHRbMF0pfSgobj0+e24uc2V0U0RLUHJvY2Vzc2luZ01ldGFkYXRhKHtbSHRdOiEwfSk7Y29uc3QgZT10KCk7cmV0dXJuIG4uc2V0U0RLUHJvY2Vzc2luZ01ldGFkYXRhKHtbSHRdOnZvaWQgMH0pLGV9KSl9dmFyIFd0O2Z1bmN0aW9uIFl0KHQpe3JldHVybiBuZXcgS3QoKG49PntuKHQpfSkpfSFmdW5jdGlvbih0KXt0W3QuUEVORElORz0wXT0iUEVORElORyI7dFt0LlJFU09MVkVEPTFdPSJSRVNPTFZFRCI7dFt0LlJFSkVDVEVEPTJdPSJSRUpFQ1RFRCJ9KFd0fHwoV3Q9e30pKTtjbGFzcyBLdHtjb25zdHJ1Y3Rvcih0KXt0aGlzLkw9V3QuUEVORElORyx0aGlzLkI9W10sdGhpcy5HKHQpfXRoZW4odCxuKXtyZXR1cm4gbmV3IEt0KCgoZSxyKT0+e3RoaXMuQi5wdXNoKFshMSxuPT57aWYodCl0cnl7ZSh0KG4pKX1jYXRjaCh0KXtyKHQpfWVsc2UgZShuKX0sdD0+e2lmKG4pdHJ5e2Uobih0KSl9Y2F0Y2godCl7cih0KX1lbHNlIHIodCl9XSksdGhpcy5KKCl9KSl9Y2F0Y2godCl7cmV0dXJuIHRoaXMudGhlbigodD0+dCksdCl9ZmluYWxseSh0KXtyZXR1cm4gbmV3IEt0KCgobixlKT0+e2xldCByLG87cmV0dXJuIHRoaXMudGhlbigobj0+e289ITEscj1uLHQmJnQoKX0pLChuPT57bz0hMCxyPW4sdCYmdCgpfSkpLnRoZW4oKCgpPT57bz9lKHIpOm4ocil9KSl9KSl9Sigpe2lmKHRoaXMuTD09PVd0LlBFTkRJTkcpcmV0dXJuO2NvbnN0IHQ9dGhpcy5CLnNsaWNlKCk7dGhpcy5CPVtdLHQuZm9yRWFjaCgodD0+e3RbMF18fCh0aGlzLkw9PT1XdC5SRVNPTFZFRCYmdFsxXSh0aGlzLkgpLHRoaXMuTD09PVd0LlJFSkVDVEVEJiZ0WzJdKHRoaXMuSCksdFswXT0hMCl9KSl9Ryh0KXtjb25zdCBuPSh0LG4pPT57dGhpcy5MPT09V3QuUEVORElORyYmKGoobik/bi50aGVuKGUscik6KHRoaXMuTD10LHRoaXMuSD1uLHRoaXMuSigpKSl9LGU9dD0+e24oV3QuUkVTT0xWRUQsdCl9LHI9dD0+e24oV3QuUkVKRUNURUQsdCl9O3RyeXt0KGUscil9Y2F0Y2godCl7cih0KX19fWZ1bmN0aW9uIFZ0KHQsbil7Y29uc3R7ZmluZ2VycHJpbnQ6ZSxzcGFuOnIsYnJlYWRjcnVtYnM6byxzZGtQcm9jZXNzaW5nTWV0YWRhdGE6c309bjshZnVuY3Rpb24odCxuKXtjb25zdHtleHRyYTplLHRhZ3M6cix1c2VyOm8sY29udGV4dHM6cyxsZXZlbDppLHRyYW5zYWN0aW9uTmFtZTpjfT1uO09iamVjdC5rZXlzKGUpLmxlbmd0aCYmKHQuZXh0cmE9ey4uLmUsLi4udC5leHRyYX0pO09iamVjdC5rZXlzKHIpLmxlbmd0aCYmKHQudGFncz17Li4uciwuLi50LnRhZ3N9KTtPYmplY3Qua2V5cyhvKS5sZW5ndGgmJih0LnVzZXI9ey4uLm8sLi4udC51c2VyfSk7T2JqZWN0LmtleXMocykubGVuZ3RoJiYodC5jb250ZXh0cz17Li4ucywuLi50LmNvbnRleHRzfSk7aSYmKHQubGV2ZWw9aSk7YyYmInRyYW5zYWN0aW9uIiE9PXQudHlwZSYmKHQudHJhbnNhY3Rpb249Yyl9KHQsbiksciYmZnVuY3Rpb24odCxuKXt0LmNvbnRleHRzPXt0cmFjZTpfdChuKSwuLi50LmNvbnRleHRzfSx0LnNka1Byb2Nlc3NpbmdNZXRhZGF0YT17ZHluYW1pY1NhbXBsaW5nQ29udGV4dDpPdChuKSwuLi50LnNka1Byb2Nlc3NpbmdNZXRhZGF0YX07Y29uc3QgZT1DdChuKSxyPUV0KGUpLmRlc2NyaXB0aW9uO3ImJiF0LnRyYW5zYWN0aW9uJiYidHJhbnNhY3Rpb24iPT09dC50eXBlJiYodC50cmFuc2FjdGlvbj1yKX0odCxyKSxmdW5jdGlvbih0LG4pe3QuZmluZ2VycHJpbnQ9dC5maW5nZXJwcmludD9BcnJheS5pc0FycmF5KHQuZmluZ2VycHJpbnQpP3QuZmluZ2VycHJpbnQ6W3QuZmluZ2VycHJpbnRdOltdLG4mJih0LmZpbmdlcnByaW50PXQuZmluZ2VycHJpbnQuY29uY2F0KG4pKTt0LmZpbmdlcnByaW50Lmxlbmd0aHx8ZGVsZXRlIHQuZmluZ2VycHJpbnR9KHQsZSksZnVuY3Rpb24odCxuKXtjb25zdCBlPVsuLi50LmJyZWFkY3J1bWJzfHxbXSwuLi5uXTt0LmJyZWFkY3J1bWJzPWUubGVuZ3RoP2U6dm9pZCAwfSh0LG8pLGZ1bmN0aW9uKHQsbil7dC5zZGtQcm9jZXNzaW5nTWV0YWRhdGE9ey4uLnQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhLC4uLm59fSh0LHMpfWNvbnN0IFp0PSI3Ijtjb25zdCBxdD1TeW1ib2wuZm9yKCJTZW50cnlCdWZmZXJGdWxsRXJyb3IiKTtmdW5jdGlvbiBRdCh0KXtjb25zdCBuPVtdO2Z1bmN0aW9uIGUodCl7cmV0dXJuIG4uc3BsaWNlKG4uaW5kZXhPZih0KSwxKVswXXx8UHJvbWlzZS5yZXNvbHZlKHZvaWQgMCl9cmV0dXJueyQ6bixhZGQ6ZnVuY3Rpb24ocil7aWYoISh2b2lkIDA9PT10fHxuLmxlbmd0aDx0KSlyZXR1cm4gbz1xdCxuZXcgS3QoKCh0LG4pPT57bihvKX0pKTt2YXIgbztjb25zdCBzPXIoKTtyZXR1cm4tMT09PW4uaW5kZXhPZihzKSYmbi5wdXNoKHMpLHMudGhlbigoKCk9PmUocykpKS50aGVuKG51bGwsKCgpPT5lKHMpLnRoZW4obnVsbCwoKCk9Pnt9KSkpKSxzfSxkcmFpbjpmdW5jdGlvbih0KXtyZXR1cm4gbmV3IEt0KCgoZSxyKT0+e2xldCBvPW4ubGVuZ3RoO2lmKCFvKXJldHVybiBlKCEwKTtjb25zdCBzPXNldFRpbWVvdXQoKCgpPT57dCYmdD4wJiZlKCExKX0pLHQpO24uZm9yRWFjaCgodD0+e1l0KHQpLnRoZW4oKCgpPT57LS1vfHwoY2xlYXJUaW1lb3V0KHMpLGUoITApKX0pLHIpfSkpfSkpfX19Y29uc3QgWHQ9NmU0O2Z1bmN0aW9uIHRuKHQse3N0YXR1c0NvZGU6bixoZWFkZXJzOmV9LHI9RGF0ZS5ub3coKSl7Y29uc3Qgbz17Li4udH0scz1lPy5bIngtc2VudHJ5LXJhdGUtbGltaXRzIl0saT1lPy5bInJldHJ5LWFmdGVyIl07aWYocylmb3IoY29uc3QgdCBvZiBzLnRyaW0oKS5zcGxpdCgiLCIpKXtjb25zdFtuLGUsLCxzXT10LnNwbGl0KCI6Iiw1KSxpPXBhcnNlSW50KG4sMTApLGM9MWUzKihpc05hTihpKT82MDppKTtpZihlKWZvcihjb25zdCB0IG9mIGUuc3BsaXQoIjsiKSkibWV0cmljX2J1Y2tldCI9PT10JiZzJiYhcy5zcGxpdCgiOyIpLmluY2x1ZGVzKCJjdXN0b20iKXx8KG9bdF09citjKTtlbHNlIG8uYWxsPXIrY31lbHNlIGk/by5hbGw9citmdW5jdGlvbih0LG49RGF0ZS5ub3coKSl7Y29uc3QgZT1wYXJzZUludChgJHt0fWAsMTApO2lmKCFpc05hTihlKSlyZXR1cm4gMWUzKmU7Y29uc3Qgcj1EYXRlLnBhcnNlKGAke3R9YCk7cmV0dXJuIGlzTmFOKHIpP1h0OnItbn0oaSxyKTo0Mjk9PT1uJiYoby5hbGw9cis2ZTQpO3JldHVybiBvfWNvbnN0IG5uPTY0O2Z1bmN0aW9uIGVuKHQsbixlPVF0KHQuYnVmZmVyU2l6ZXx8bm4pKXtsZXQgcj17fTtyZXR1cm57c2VuZDpmdW5jdGlvbih0KXtjb25zdCBvPVtdO2lmKE10KHQsKCh0LG4pPT57Y29uc3QgZT1mdW5jdGlvbih0KXtyZXR1cm4gR3RbdF19KG4pOyhmdW5jdGlvbih0LG4sZT1EYXRlLm5vdygpKXtyZXR1cm4gZnVuY3Rpb24odCxuKXtyZXR1cm4gdFtuXXx8dC5hbGx8fDB9KHQsbik+ZX0pKHIsZSl8fG8ucHVzaCh0KX0pKSwwPT09by5sZW5ndGgpcmV0dXJuIFl0KHt9KTtjb25zdCBzPVV0KHRbMF0sbyksaT10PT57TXQocywoKHQsbik9Pnt9KSl9O3JldHVybiBlLmFkZCgoKCk9Pm4oe2JvZHk6QnQocyl9KS50aGVuKCh0PT4odm9pZCAwIT09dC5zdGF0dXNDb2RlJiYodC5zdGF0dXNDb2RlPDIwMHx8dC5zdGF0dXNDb2RlPj0zMDApJiZoJiZfLndhcm4oYFNlbnRyeSByZXNwb25kZWQgd2l0aCBzdGF0dXMgY29kZSAke3Quc3RhdHVzQ29kZX0gdG8gc2VudCBldmVudC5gKSxyPXRuKHIsdCksdCkpLCh0PT57dGhyb3cgaSgpLGgmJl8uZXJyb3IoIkVuY291bnRlcmVkIGVycm9yIHJ1bm5pbmcgdHJhbnNwb3J0IHJlcXVlc3Q6Iix0KSx0fSkpKSkudGhlbigodD0+dCksKHQ9PntpZih0PT09cXQpcmV0dXJuIGgmJl8uZXJyb3IoIlNraXBwZWQgc2VuZGluZyBldmVudCBiZWNhdXNlIGJ1ZmZlciBpcyBmdWxsLiIpLGkoKSxZdCh7fSk7dGhyb3cgdH0pKX0sZmx1c2g6dD0+ZS5kcmFpbih0KX19Y29uc3Qgcm49L14oXFMrOlxcfFwvPykoW1xzXFNdKj8pKCg/OlwuezEsMn18W14vXFxdKz98KShcLlteLi9cXF0qfCkpKD86Wy9cXF0qKSQvO2Z1bmN0aW9uIG9uKHQpe2NvbnN0IG49ZnVuY3Rpb24odCl7Y29uc3Qgbj10Lmxlbmd0aD4xMDI0P2A8dHJ1bmNhdGVkPiR7dC5zbGljZSgtMTAyNCl9YDp0LGU9cm4uZXhlYyhuKTtyZXR1cm4gZT9lLnNsaWNlKDEpOltdfSh0KSxlPW5bMF18fCIiO2xldCByPW5bMV07cmV0dXJuIGV8fHI/KHImJihyPXIuc2xpY2UoMCxyLmxlbmd0aC0xKSksZStyKToiLiJ9ZnVuY3Rpb24gc24odCxuPSExKXtyZXR1cm4hKG58fHQmJiF0LnN0YXJ0c1dpdGgoIi8iKSYmIXQubWF0Y2goL15bQS1aXTovKSYmIXQuc3RhcnRzV2l0aCgiLiIpJiYhdC5tYXRjaCgvXlthLXpBLVpdKFthLXpBLVowLTkuXC0rXSkqOlwvXC8vKSkmJnZvaWQgMCE9PXQmJiF0LmluY2x1ZGVzKCJub2RlX21vZHVsZXMvIil9Y29uc3QgY249U3ltYm9sKCJBZ2VudEJhc2VJbnRlcm5hbFN0YXRlIik7Y2xhc3MgdW4gZXh0ZW5kcyBzLkFnZW50e2NvbnN0cnVjdG9yKHQpe3N1cGVyKHQpLHRoaXNbY25dPXt9fWlzU2VjdXJlRW5kcG9pbnQodCl7aWYodCl7aWYoImJvb2xlYW4iPT10eXBlb2YgdC5zZWN1cmVFbmRwb2ludClyZXR1cm4gdC5zZWN1cmVFbmRwb2ludDtpZigic3RyaW5nIj09dHlwZW9mIHQucHJvdG9jb2wpcmV0dXJuImh0dHBzOiI9PT10LnByb3RvY29sfWNvbnN0e3N0YWNrOm59PW5ldyBFcnJvcjtyZXR1cm4ic3RyaW5nIj09dHlwZW9mIG4mJm4uc3BsaXQoIlxuIikuc29tZSgodD0+LTEhPT10LmluZGV4T2YoIihodHRwcy5qczoiKXx8LTEhPT10LmluZGV4T2YoIm5vZGU6aHR0cHM6IikpKX1jcmVhdGVTb2NrZXQodCxuLGUpe2NvbnN0IHI9ey4uLm4sc2VjdXJlRW5kcG9pbnQ6dGhpcy5pc1NlY3VyZUVuZHBvaW50KG4pfTtQcm9taXNlLnJlc29sdmUoKS50aGVuKCgoKT0+dGhpcy5jb25uZWN0KHQscikpKS50aGVuKChvPT57aWYobyBpbnN0YW5jZW9mIHMuQWdlbnQpcmV0dXJuIG8uYWRkUmVxdWVzdCh0LHIpO3RoaXNbY25dLmN1cnJlbnRTb2NrZXQ9byxzdXBlci5jcmVhdGVTb2NrZXQodCxuLGUpfSksZSl9Y3JlYXRlQ29ubmVjdGlvbigpe2NvbnN0IHQ9dGhpc1tjbl0uY3VycmVudFNvY2tldDtpZih0aGlzW2NuXS5jdXJyZW50U29ja2V0PXZvaWQgMCwhdCl0aHJvdyBuZXcgRXJyb3IoIk5vIHNvY2tldCB3YXMgcmV0dXJuZWQgaW4gdGhlIGBjb25uZWN0KClgIGZ1bmN0aW9uIik7cmV0dXJuIHR9Z2V0IGRlZmF1bHRQb3J0KCl7cmV0dXJuIHRoaXNbY25dLmRlZmF1bHRQb3J0Pz8oImh0dHBzOiI9PT10aGlzLnByb3RvY29sPzQ0Mzo4MCl9c2V0IGRlZmF1bHRQb3J0KHQpe3RoaXNbY25dJiYodGhpc1tjbl0uZGVmYXVsdFBvcnQ9dCl9Z2V0IHByb3RvY29sKCl7cmV0dXJuIHRoaXNbY25dLnByb3RvY29sPz8odGhpcy5pc1NlY3VyZUVuZHBvaW50KCk/Imh0dHBzOiI6Imh0dHA6Iil9c2V0IHByb3RvY29sKHQpe3RoaXNbY25dJiYodGhpc1tjbl0ucHJvdG9jb2w9dCl9fWZ1bmN0aW9uIGFuKC4uLnQpe18ubG9nKCJbaHR0cHMtcHJveHktYWdlbnQ6cGFyc2UtcHJveHktcmVzcG9uc2VdIiwuLi50KX1mdW5jdGlvbiBmbih0KXtyZXR1cm4gbmV3IFByb21pc2UoKChuLGUpPT57bGV0IHI9MDtjb25zdCBvPVtdO2Z1bmN0aW9uIHMoKXtjb25zdCBjPXQucmVhZCgpO2M/ZnVuY3Rpb24oYyl7by5wdXNoKGMpLHIrPWMubGVuZ3RoO2NvbnN0IHU9QnVmZmVyLmNvbmNhdChvLHIpLGE9dS5pbmRleE9mKCJcclxuXHJcbiIpO2lmKC0xPT09YSlyZXR1cm4gYW4oImhhdmUgbm90IHJlY2VpdmVkIGVuZCBvZiBIVFRQIGhlYWRlcnMgeWV0Li4uIiksdm9pZCBzKCk7Y29uc3QgZj11LnN1YmFycmF5KDAsYSkudG9TdHJpbmcoImFzY2lpIikuc3BsaXQoIlxyXG4iKSxoPWYuc2hpZnQoKTtpZighaClyZXR1cm4gdC5kZXN0cm95KCksZShuZXcgRXJyb3IoIk5vIGhlYWRlciByZWNlaXZlZCBmcm9tIHByb3h5IENPTk5FQ1QgcmVzcG9uc2UiKSk7Y29uc3QgcD1oLnNwbGl0KCIgIiksbD0rKHBbMV18fDApLGQ9cC5zbGljZSgyKS5qb2luKCIgIiksbT17fTtmb3IoY29uc3QgbiBvZiBmKXtpZighbiljb250aW51ZTtjb25zdCByPW4uaW5kZXhPZigiOiIpO2lmKC0xPT09cilyZXR1cm4gdC5kZXN0cm95KCksZShuZXcgRXJyb3IoYEludmFsaWQgaGVhZGVyIGZyb20gcHJveHkgQ09OTkVDVCByZXNwb25zZTogIiR7bn0iYCkpO2NvbnN0IG89bi5zbGljZSgwLHIpLnRvTG93ZXJDYXNlKCkscz1uLnNsaWNlKHIrMSkudHJpbVN0YXJ0KCksaT1tW29dOyJzdHJpbmciPT10eXBlb2YgaT9tW29dPVtpLHNdOkFycmF5LmlzQXJyYXkoaSk/aS5wdXNoKHMpOm1bb109c31hbigiZ290IHByb3h5IHNlcnZlciByZXNwb25zZTogJW8gJW8iLGgsbSksaSgpLG4oe2Nvbm5lY3Q6e3N0YXR1c0NvZGU6bCxzdGF0dXNUZXh0OmQsaGVhZGVyczptfSxidWZmZXJlZDp1fSl9KGMpOnQub25jZSgicmVhZGFibGUiLHMpfWZ1bmN0aW9uIGkoKXt0LnJlbW92ZUxpc3RlbmVyKCJlbmQiLGMpLHQucmVtb3ZlTGlzdGVuZXIoImVycm9yIix1KSx0LnJlbW92ZUxpc3RlbmVyKCJyZWFkYWJsZSIscyl9ZnVuY3Rpb24gYygpe2koKSxhbigib25lbmQiKSxlKG5ldyBFcnJvcigiUHJveHkgY29ubmVjdGlvbiBlbmRlZCBiZWZvcmUgcmVjZWl2aW5nIENPTk5FQ1QgcmVzcG9uc2UiKSl9ZnVuY3Rpb24gdSh0KXtpKCksYW4oIm9uZXJyb3IgJW8iLHQpLGUodCl9dC5vbigiZXJyb3IiLHUpLHQub24oImVuZCIsYykscygpfSkpfWZ1bmN0aW9uIGhuKC4uLnQpe18ubG9nKCJbaHR0cHMtcHJveHktYWdlbnRdIiwuLi50KX1jbGFzcyBwbiBleHRlbmRzIHVue3N0YXRpYyBfX2luaXRTdGF0aWMoKXt0aGlzLnByb3RvY29scz1bImh0dHAiLCJodHRwcyJdfWNvbnN0cnVjdG9yKHQsbil7c3VwZXIobiksdGhpcy5vcHRpb25zPXt9LHRoaXMucHJveHk9InN0cmluZyI9PXR5cGVvZiB0P25ldyBVUkwodCk6dCx0aGlzLnByb3h5SGVhZGVycz1uPy5oZWFkZXJzPz97fSxobigiQ3JlYXRpbmcgbmV3IEh0dHBzUHJveHlBZ2VudCBpbnN0YW5jZTogJW8iLHRoaXMucHJveHkuaHJlZik7Y29uc3QgZT0odGhpcy5wcm94eS5ob3N0bmFtZXx8dGhpcy5wcm94eS5ob3N0KS5yZXBsYWNlKC9eXFt8XF0kL2csIiIpLHI9dGhpcy5wcm94eS5wb3J0P3BhcnNlSW50KHRoaXMucHJveHkucG9ydCwxMCk6Imh0dHBzOiI9PT10aGlzLnByb3h5LnByb3RvY29sPzQ0Mzo4MDt0aGlzLmNvbm5lY3RPcHRzPXtBTFBOUHJvdG9jb2xzOlsiaHR0cC8xLjEiXSwuLi5uP2RuKG4sImhlYWRlcnMiKTpudWxsLGhvc3Q6ZSxwb3J0OnJ9fWFzeW5jIGNvbm5lY3QodCxuKXtjb25zdHtwcm94eTplfT10aGlzO2lmKCFuLmhvc3QpdGhyb3cgbmV3IFR5cGVFcnJvcignTm8gImhvc3QiIHByb3ZpZGVkJyk7bGV0IHI7aWYoImh0dHBzOiI9PT1lLnByb3RvY29sKXtobigiQ3JlYXRpbmcgYHRscy5Tb2NrZXRgOiAlbyIsdGhpcy5jb25uZWN0T3B0cyk7Y29uc3QgdD10aGlzLmNvbm5lY3RPcHRzLnNlcnZlcm5hbWV8fHRoaXMuY29ubmVjdE9wdHMuaG9zdDtyPWYuY29ubmVjdCh7Li4udGhpcy5jb25uZWN0T3B0cyxzZXJ2ZXJuYW1lOnQmJmEuaXNJUCh0KT92b2lkIDA6dH0pfWVsc2UgaG4oIkNyZWF0aW5nIGBuZXQuU29ja2V0YDogJW8iLHRoaXMuY29ubmVjdE9wdHMpLHI9YS5jb25uZWN0KHRoaXMuY29ubmVjdE9wdHMpO2NvbnN0IG89ImZ1bmN0aW9uIj09dHlwZW9mIHRoaXMucHJveHlIZWFkZXJzP3RoaXMucHJveHlIZWFkZXJzKCk6ey4uLnRoaXMucHJveHlIZWFkZXJzfSxzPWEuaXNJUHY2KG4uaG9zdCk/YFske24uaG9zdH1dYDpuLmhvc3Q7bGV0IGk9YENPTk5FQ1QgJHtzfToke24ucG9ydH0gSFRUUC8xLjFcclxuYDtpZihlLnVzZXJuYW1lfHxlLnBhc3N3b3JkKXtjb25zdCB0PWAke2RlY29kZVVSSUNvbXBvbmVudChlLnVzZXJuYW1lKX06JHtkZWNvZGVVUklDb21wb25lbnQoZS5wYXNzd29yZCl9YDtvWyJQcm94eS1BdXRob3JpemF0aW9uIl09YEJhc2ljICR7QnVmZmVyLmZyb20odCkudG9TdHJpbmcoImJhc2U2NCIpfWB9by5Ib3N0PWAke3N9OiR7bi5wb3J0fWAsb1siUHJveHktQ29ubmVjdGlvbiJdfHwob1siUHJveHktQ29ubmVjdGlvbiJdPXRoaXMua2VlcEFsaXZlPyJLZWVwLUFsaXZlIjoiY2xvc2UiKTtmb3IoY29uc3QgdCBvZiBPYmplY3Qua2V5cyhvKSlpKz1gJHt0fTogJHtvW3RdfVxyXG5gO2NvbnN0IGM9Zm4ocik7ci53cml0ZShgJHtpfVxyXG5gKTtjb25zdHtjb25uZWN0OnUsYnVmZmVyZWQ6aH09YXdhaXQgYztpZih0LmVtaXQoInByb3h5Q29ubmVjdCIsdSksdGhpcy5lbWl0KCJwcm94eUNvbm5lY3QiLHUsdCksMjAwPT09dS5zdGF0dXNDb2RlKXtpZih0Lm9uY2UoInNvY2tldCIsbG4pLG4uc2VjdXJlRW5kcG9pbnQpe2huKCJVcGdyYWRpbmcgc29ja2V0IGNvbm5lY3Rpb24gdG8gVExTIik7Y29uc3QgdD1uLnNlcnZlcm5hbWV8fG4uaG9zdDtyZXR1cm4gZi5jb25uZWN0KHsuLi5kbihuLCJob3N0IiwicGF0aCIsInBvcnQiKSxzb2NrZXQ6cixzZXJ2ZXJuYW1lOmEuaXNJUCh0KT92b2lkIDA6dH0pfXJldHVybiByfXIuZGVzdHJveSgpO2NvbnN0IHA9bmV3IGEuU29ja2V0KHt3cml0YWJsZTohMX0pO3JldHVybiBwLnJlYWRhYmxlPSEwLHQub25jZSgic29ja2V0IiwodD0+e2huKCJSZXBsYXlpbmcgcHJveHkgYnVmZmVyIGZvciBmYWlsZWQgcmVxdWVzdCIpLHQucHVzaChoKSx0LnB1c2gobnVsbCl9KSkscH19ZnVuY3Rpb24gbG4odCl7dC5yZXN1bWUoKX1mdW5jdGlvbiBkbih0LC4uLm4pe2NvbnN0IGU9e307bGV0IHI7Zm9yKHIgaW4gdCluLmluY2x1ZGVzKHIpfHwoZVtyXT10W3JdKTtyZXR1cm4gZX1wbi5fX2luaXRTdGF0aWMoKTtjb25zdCBtbj0zMjc2ODtmdW5jdGlvbiBnbih0KXtyZXR1cm4gdC5yZXBsYWNlKC9eW0EtWl06LywiIikucmVwbGFjZSgvXFwvZywiLyIpfWNvbnN0IHluPW47bGV0IGJuLHZuPTAsX249e307ZnVuY3Rpb24gd24odCl7eW4uZGVidWcmJmNvbnNvbGUubG9nKGBbQU5SIFdvcmtlcl0gJHt0fWApfXZhciBTbiwkbixFbjtjb25zdCB4bj1mdW5jdGlvbih0KXtsZXQgbjt0cnl7bj1uZXcgVVJMKHQudXJsKX1jYXRjaChuKXtyZXR1cm4gdigoKCk9Pntjb25zb2xlLndhcm4oIltAc2VudHJ5L25vZGVdOiBJbnZhbGlkIGRzbiBvciB0dW5uZWwgb3B0aW9uLCB3aWxsIG5vdCBzZW5kIGFueSBldmVudHMuIFRoZSB0dW5uZWwgb3B0aW9uIG11c3QgYmUgYSBmdWxsIFVSTCB3aGVuIHVzZWQuIil9KSksZW4odCwoKCk9PlByb21pc2UucmVzb2x2ZSh7fSkpKX1jb25zdCBlPSJodHRwczoiPT09bi5wcm90b2NvbCxyPWZ1bmN0aW9uKHQsbil7Y29uc3R7bm9fcHJveHk6ZX09cHJvY2Vzcy5lbnYscj1lPy5zcGxpdCgiLCIpLnNvbWUoKG49PnQuaG9zdC5lbmRzV2l0aChuKXx8dC5ob3N0bmFtZS5lbmRzV2l0aChuKSkpO3JldHVybiByP3ZvaWQgMDpufShuLHQucHJveHl8fChlP3Byb2Nlc3MuZW52Lmh0dHBzX3Byb3h5OnZvaWQgMCl8fHByb2Nlc3MuZW52Lmh0dHBfcHJveHkpLG89ZT9pOnMsYT12b2lkIDAhPT10LmtlZXBBbGl2ZSYmdC5rZWVwQWxpdmUsZj1yP25ldyBwbihyKTpuZXcgby5BZ2VudCh7a2VlcEFsaXZlOmEsbWF4U29ja2V0czozMCx0aW1lb3V0OjJlM30pLGg9ZnVuY3Rpb24odCxuLGUpe2NvbnN0e2hvc3RuYW1lOnIscGF0aG5hbWU6byxwb3J0OnMscHJvdG9jb2w6aSxzZWFyY2g6YX09bmV3IFVSTCh0LnVybCk7cmV0dXJuIGZ1bmN0aW9uKGYpe3JldHVybiBuZXcgUHJvbWlzZSgoKGgscCk9PntGdCgoKCk9PntsZXQgbD1mdW5jdGlvbih0KXtyZXR1cm4gbmV3IGMoe3JlYWQoKXt0aGlzLnB1c2godCksdGhpcy5wdXNoKG51bGwpfX0pfShmLmJvZHkpO2NvbnN0IGQ9ey4uLnQuaGVhZGVyc307Zi5ib2R5Lmxlbmd0aD5tbiYmKGRbImNvbnRlbnQtZW5jb2RpbmciXT0iZ3ppcCIsbD1sLnBpcGUodSgpKSk7Y29uc3QgbT1uLnJlcXVlc3Qoe21ldGhvZDoiUE9TVCIsYWdlbnQ6ZSxoZWFkZXJzOmQsaG9zdG5hbWU6cixwYXRoOmAke299JHthfWAscG9ydDpzLHByb3RvY29sOmksY2E6dC5jYUNlcnRzfSwodD0+e3Qub24oImRhdGEiLCgoKT0+e30pKSx0Lm9uKCJlbmQiLCgoKT0+e30pKSx0LnNldEVuY29kaW5nKCJ1dGY4Iik7Y29uc3Qgbj10LmhlYWRlcnNbInJldHJ5LWFmdGVyIl0/P251bGwsZT10LmhlYWRlcnNbIngtc2VudHJ5LXJhdGUtbGltaXRzIl0/P251bGw7aCh7c3RhdHVzQ29kZTp0LnN0YXR1c0NvZGUsaGVhZGVyczp7InJldHJ5LWFmdGVyIjpuLCJ4LXNlbnRyeS1yYXRlLWxpbWl0cyI6QXJyYXkuaXNBcnJheShlKT9lWzBdfHxudWxsOmV9fSl9KSk7bS5vbigiZXJyb3IiLHApLGwucGlwZShtKX0pKX0pKX19KHQsdC5odHRwTW9kdWxlPz9vLGYpO3JldHVybiBlbih0LGgpfSh7dXJsOihTbj15bi5kc24sJG49eW4udHVubmVsLEVuPXluLnNka01ldGFkYXRhLnNkaywkbnx8YCR7ZnVuY3Rpb24odCl7cmV0dXJuYCR7ZnVuY3Rpb24odCl7Y29uc3Qgbj10LnByb3RvY29sP2Ake3QucHJvdG9jb2x9OmA6IiIsZT10LnBvcnQ/YDoke3QucG9ydH1gOiIiO3JldHVybmAke259Ly8ke3QuaG9zdH0ke2V9JHt0LnBhdGg/YC8ke3QucGF0aH1gOiIifS9hcGkvYH0odCl9JHt0LnByb2plY3RJZH0vZW52ZWxvcGUvYH0oU24pfT8ke2Z1bmN0aW9uKHQsbil7Y29uc3QgZT17c2VudHJ5X3ZlcnNpb246WnR9O3JldHVybiB0LnB1YmxpY0tleSYmKGUuc2VudHJ5X2tleT10LnB1YmxpY0tleSksbiYmKGUuc2VudHJ5X2NsaWVudD1gJHtuLm5hbWV9LyR7bi52ZXJzaW9ufWApLG5ldyBVUkxTZWFyY2hQYXJhbXMoZSkudG9TdHJpbmcoKX0oU24sRW4pfWApfSk7YXN5bmMgZnVuY3Rpb24gTm4oKXtpZihibil7d24oIlNlbmRpbmcgYWJub3JtYWwgc2Vzc2lvbiIpLEgoYm4se3N0YXR1czoiYWJub3JtYWwiLGFibm9ybWFsX21lY2hhbmlzbToiYW5yX2ZvcmVncm91bmQiLHJlbGVhc2U6eW4ucmVsZWFzZSxlbnZpcm9ubWVudDp5bi5lbnZpcm9ubWVudH0pO2NvbnN0IHQ9ZnVuY3Rpb24odCxuLGUscil7Y29uc3Qgbz1KdChlKTtyZXR1cm4gVXQoe3NlbnRfYXQ6KG5ldyBEYXRlKS50b0lTT1N0cmluZygpLC4uLm8mJntzZGs6b30sLi4uISFyJiZuJiZ7ZHNuOmp0KG4pfX0sWyJhZ2dyZWdhdGVzImluIHQ/W3t0eXBlOiJzZXNzaW9ucyJ9LHRdOlt7dHlwZToic2Vzc2lvbiJ9LHQudG9KU09OKCldXSl9KGJuLHluLmRzbix5bi5zZGtNZXRhZGF0YSx5bi50dW5uZWwpO3duKEpTT04uc3RyaW5naWZ5KHQpKSxhd2FpdCB4bi5zZW5kKHQpO3RyeXtlPy5wb3N0TWVzc2FnZSgic2Vzc2lvbi1lbmRlZCIpfWNhdGNoKHQpe319fWZ1bmN0aW9uIENuKHQpe2lmKCF0KXJldHVybjtjb25zdCBuPWZ1bmN0aW9uKHQpe2lmKCF0Lmxlbmd0aClyZXR1cm5bXTtjb25zdCBuPUFycmF5LmZyb20odCk7cmV0dXJuL3NlbnRyeVdyYXBwZWQvLnRlc3QoRShuKS5mdW5jdGlvbnx8IiIpJiZuLnBvcCgpLG4ucmV2ZXJzZSgpLCQudGVzdChFKG4pLmZ1bmN0aW9ufHwiIikmJihuLnBvcCgpLCQudGVzdChFKG4pLmZ1bmN0aW9ufHwiIikmJm4ucG9wKCkpLG4uc2xpY2UoMCx3KS5tYXAoKHQ9Pih7Li4udCxmaWxlbmFtZTp0LmZpbGVuYW1lfHxFKG4pLmZpbGVuYW1lLGZ1bmN0aW9uOnQuZnVuY3Rpb258fFN9KSkpfSh0KTtpZih5bi5hcHBSb290UGF0aClmb3IoY29uc3QgdCBvZiBuKXQuZmlsZW5hbWUmJih0LmZpbGVuYW1lPVB0KHQuZmlsZW5hbWUseW4uYXBwUm9vdFBhdGgpKTtyZXR1cm4gbn1hc3luYyBmdW5jdGlvbiBUbih0LG4pe2lmKHZuPj15bi5tYXhBbnJFdmVudHMpcmV0dXJuO3ZuKz0xLGF3YWl0IE5uKCksd24oIlNlbmRpbmcgZXZlbnQiKTtjb25zdCBlPXtldmVudF9pZDpMKCksY29udGV4dHM6eW4uY29udGV4dHMscmVsZWFzZTp5bi5yZWxlYXNlLGVudmlyb25tZW50OnluLmVudmlyb25tZW50LGRpc3Q6eW4uZGlzdCxwbGF0Zm9ybToibm9kZSIsbGV2ZWw6ImVycm9yIixleGNlcHRpb246e3ZhbHVlczpbe3R5cGU6IkFwcGxpY2F0aW9uTm90UmVzcG9uZGluZyIsdmFsdWU6YEFwcGxpY2F0aW9uIE5vdCBSZXNwb25kaW5nIGZvciBhdCBsZWFzdCAke3luLmFuclRocmVzaG9sZH0gbXNgLHN0YWNrdHJhY2U6e2ZyYW1lczpDbih0KX0sbWVjaGFuaXNtOnt0eXBlOiJBTlIifX1dfSx0YWdzOnluLnN0YXRpY1RhZ3N9O24mJmZ1bmN0aW9uKHQsbil7aWYoVnQodCxuKSwhdC5jb250ZXh0cz8udHJhY2Upe2NvbnN0e3RyYWNlSWQ6ZSxwYXJlbnRTcGFuSWQ6cixwcm9wYWdhdGlvblNwYW5JZDpvfT1uLnByb3BhZ2F0aW9uQ29udGV4dDt0LmNvbnRleHRzPXt0cmFjZTp7dHJhY2VfaWQ6ZSxzcGFuX2lkOm98fFkoKSxwYXJlbnRfc3Bhbl9pZDpyfSwuLi50LmNvbnRleHRzfX19KGUsbiksZnVuY3Rpb24odCl7aWYoMD09PU9iamVjdC5rZXlzKF9uKS5sZW5ndGgpcmV0dXJuO2NvbnN0IG49eW4uYXBwUm9vdFBhdGg/e306X247aWYoeW4uYXBwUm9vdFBhdGgpZm9yKGNvbnN0W3QsZV1vZiBPYmplY3QuZW50cmllcyhfbikpbltQdCh0LHluLmFwcFJvb3RQYXRoKV09ZTtjb25zdCBlPW5ldyBNYXA7Zm9yKGNvbnN0IHIgb2YgdC5leGNlcHRpb24/LnZhbHVlc3x8W10pZm9yKGNvbnN0IHQgb2Ygci5zdGFja3RyYWNlPy5mcmFtZXN8fFtdKXtjb25zdCByPXQuYWJzX3BhdGh8fHQuZmlsZW5hbWU7ciYmbltyXSYmZS5zZXQocixuW3JdKX1pZihlLnNpemU+MCl7Y29uc3Qgbj1bXTtmb3IoY29uc3RbdCxyXW9mIGUuZW50cmllcygpKW4ucHVzaCh7dHlwZToic291cmNlbWFwIixjb2RlX2ZpbGU6dCxkZWJ1Z19pZDpyfSk7dC5kZWJ1Z19tZXRhPXtpbWFnZXM6bn19fShlKTtjb25zdCByPXp0KGUseW4uZHNuLHluLnNka01ldGFkYXRhLHluLnR1bm5lbCk7d24oSlNPTi5zdHJpbmdpZnkocikpLGF3YWl0IHhuLnNlbmQociksYXdhaXQgeG4uZmx1c2goMmUzKSx2bj49eW4ubWF4QW5yRXZlbnRzJiZzZXRUaW1lb3V0KCgoKT0+e3Byb2Nlc3MuZXhpdCgwKX0pLDVlMyl9bGV0IGtuO2lmKHduKCJTdGFydGVkIikseW4uY2FwdHVyZVN0YWNrVHJhY2Upe3duKCJDb25uZWN0aW5nIHRvIGRlYnVnZ2VyIik7Y29uc3Qgbj1uZXcgdDtuLmNvbm5lY3RUb01haW5UaHJlYWQoKSx3bigiQ29ubmVjdGVkIHRvIGRlYnVnZ2VyIik7Y29uc3QgZT1uZXcgTWFwO24ub24oIkRlYnVnZ2VyLnNjcmlwdFBhcnNlZCIsKHQ9PntlLnNldCh0LnBhcmFtcy5zY3JpcHRJZCx0LnBhcmFtcy51cmwpfSkpLG4ub24oIkRlYnVnZ2VyLnBhdXNlZCIsKHQ9PntpZigib3RoZXIiPT09dC5wYXJhbXMucmVhc29uKXRyeXt3bigiRGVidWdnZXIgcGF1c2VkIik7Y29uc3Qgcz1bLi4udC5wYXJhbXMuY2FsbEZyYW1lc10saT15bi5hcHBSb290UGF0aD9mdW5jdGlvbih0PShwcm9jZXNzLmFyZ3ZbMV0/b24ocHJvY2Vzcy5hcmd2WzFdKTpwcm9jZXNzLmN3ZCgpKSxuPSJcXCI9PT1vKXtjb25zdCBlPW4/Z24odCk6dDtyZXR1cm4gdD0+e2lmKCF0KXJldHVybjtjb25zdCBvPW4/Z24odCk6dDtsZXR7ZGlyOnMsYmFzZTppLGV4dDpjfT1yLnBhcnNlKG8pOyIuanMiIT09YyYmIi5tanMiIT09YyYmIi5janMiIT09Y3x8KGk9aS5zbGljZSgwLC0xKmMubGVuZ3RoKSk7Y29uc3QgdT1kZWNvZGVVUklDb21wb25lbnQoaSk7c3x8KHM9Ii4iKTtjb25zdCBhPXMubGFzdEluZGV4T2YoIi9ub2RlX21vZHVsZXMiKTtpZihhPi0xKXJldHVybmAke3Muc2xpY2UoYSsxNCkucmVwbGFjZSgvXC8vZywiLiIpfToke3V9YDtpZihzLnN0YXJ0c1dpdGgoZSkpe2NvbnN0IHQ9cy5zbGljZShlLmxlbmd0aCsxKS5yZXBsYWNlKC9cLy9nLCIuIik7cmV0dXJuIHQ/YCR7dH06JHt1fWA6dX1yZXR1cm4gdX19KHluLmFwcFJvb3RQYXRoKTooKT0+e30sYz1zLm1hcCgodD0+ZnVuY3Rpb24odCxuLGUpe2NvbnN0IHI9bj9uLnJlcGxhY2UoL15maWxlOlwvXC8vLCIiKTp2b2lkIDAsbz10LmxvY2F0aW9uLmNvbHVtbk51bWJlcj90LmxvY2F0aW9uLmNvbHVtbk51bWJlcisxOnZvaWQgMCxzPXQubG9jYXRpb24ubGluZU51bWJlcj90LmxvY2F0aW9uLmxpbmVOdW1iZXIrMTp2b2lkIDA7cmV0dXJue2ZpbGVuYW1lOnIsbW9kdWxlOmUociksZnVuY3Rpb246dC5mdW5jdGlvbk5hbWV8fFMsY29sbm86byxsaW5lbm86cyxpbl9hcHA6cj9zbihyKTp2b2lkIDB9fSh0LGUuZ2V0KHQubG9jYXRpb24uc2NyaXB0SWQpLGkpKSksdT1zZXRUaW1lb3V0KCgoKT0+e1RuKGMpLnRoZW4obnVsbCwoKCk9Pnt3bigiU2VuZGluZyBBTlIgZXZlbnQgZmFpbGVkLiIpfSkpfSksNWUzKTtuLnBvc3QoIlJ1bnRpbWUuZXZhbHVhdGUiLHtleHByZXNzaW9uOiJnbG9iYWwuX19TRU5UUllfR0VUX1NDT1BFU19fKCk7IixzaWxlbnQ6ITAscmV0dXJuQnlWYWx1ZTohMH0sKCh0LGUpPT57dCYmd24oYEVycm9yIGV4ZWN1dGluZyBzY3JpcHQ6ICcke3QubWVzc2FnZX0nYCksY2xlYXJUaW1lb3V0KHUpO2NvbnN0IHI9ZT8ucmVzdWx0P2UucmVzdWx0LnZhbHVlOnZvaWQgMDtuLnBvc3QoIkRlYnVnZ2VyLnJlc3VtZSIpLG4ucG9zdCgiRGVidWdnZXIuZGlzYWJsZSIpLFRuKGMscikudGhlbihudWxsLCgoKT0+e3duKCJTZW5kaW5nIEFOUiBldmVudCBmYWlsZWQuIil9KSl9KSl9Y2F0Y2godCl7dGhyb3cgbi5wb3N0KCJEZWJ1Z2dlci5yZXN1bWUiKSxuLnBvc3QoIkRlYnVnZ2VyLmRpc2FibGUiKSx0fX0pKSxrbj0oKT0+e3RyeXtuLnBvc3QoIkRlYnVnZ2VyLmVuYWJsZSIsKCgpPT57bi5wb3N0KCJEZWJ1Z2dlci5wYXVzZSIpfSkpfWNhdGNoKHQpe319fWNvbnN0e3BvbGw6am59PWZ1bmN0aW9uKHQsbixlLHIpe2NvbnN0IG89dCgpO2xldCBzPSExLGk9ITA7cmV0dXJuIHNldEludGVydmFsKCgoKT0+e2NvbnN0IHQ9by5nZXRUaW1lTXMoKTshMT09PXMmJnQ+bitlJiYocz0hMCxpJiZyKCkpLHQ8bitlJiYocz0hMSl9KSwyMCkse3BvbGw6KCk9PntvLnJlc2V0KCl9LGVuYWJsZWQ6dD0+e2k9dH19fSgoZnVuY3Rpb24oKXtsZXQgdD1wcm9jZXNzLmhydGltZSgpO3JldHVybntnZXRUaW1lTXM6KCk9Pntjb25zdFtuLGVdPXByb2Nlc3MuaHJ0aW1lKHQpO3JldHVybiBNYXRoLmZsb29yKDFlMypuK2UvMWU2KX0scmVzZXQ6KCk9Pnt0PXByb2Nlc3MuaHJ0aW1lKCl9fX0pLHluLnBvbGxJbnRlcnZhbCx5bi5hbnJUaHJlc2hvbGQsKGZ1bmN0aW9uKCl7d24oIldhdGNoZG9nIHRpbWVvdXQiKSxrbj8od24oIlBhdXNpbmcgZGVidWdnZXIgdG8gY2FwdHVyZSBzdGFjayB0cmFjZSIpLGtuKCkpOih3bigiQ2FwdHVyaW5nIGV2ZW50IHdpdGhvdXQgYSBzdGFjayB0cmFjZSIpLFRuKCkudGhlbihudWxsLCgoKT0+e3duKCJTZW5kaW5nIEFOUiBldmVudCBmYWlsZWQgb24gd2F0Y2hkb2cgdGltZW91dC4iKX0pKSl9KSk7ZT8ub24oIm1lc3NhZ2UiLCh0PT57dC5zZXNzaW9uJiYoYm49eih0LnNlc3Npb24pKSx0LmRlYnVnSW1hZ2VzJiYoX249dC5kZWJ1Z0ltYWdlcyksam4oKX0pKTs=';
|
|
13
|
-
|
|
14
|
-
const DEFAULT_INTERVAL = 50;
|
|
15
|
-
const DEFAULT_HANG_THRESHOLD = 5000;
|
|
16
|
-
|
|
17
|
-
function log(message, ...args) {
|
|
18
|
-
core.logger.log(`[ANR] ${message}`, ...args);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function globalWithScopeFetchFn() {
|
|
22
|
-
return core.GLOBAL_OBJ;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/** Fetches merged scope data */
|
|
26
|
-
function getScopeData() {
|
|
27
|
-
const scope = core.getGlobalScope().getScopeData();
|
|
28
|
-
core.mergeScopeData(scope, core.getIsolationScope().getScopeData());
|
|
29
|
-
core.mergeScopeData(scope, core.getCurrentScope().getScopeData());
|
|
30
|
-
|
|
31
|
-
// We remove attachments because they likely won't serialize well as json
|
|
32
|
-
scope.attachments = [];
|
|
33
|
-
// We can't serialize event processor functions
|
|
34
|
-
scope.eventProcessors = [];
|
|
35
|
-
|
|
36
|
-
return scope;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Gets contexts by calling all event processors. This shouldn't be called until all integrations are setup
|
|
41
|
-
*/
|
|
42
|
-
async function getContexts(client) {
|
|
43
|
-
let event = { message: 'ANR' };
|
|
44
|
-
const eventHint = {};
|
|
45
|
-
|
|
46
|
-
for (const processor of client.getEventProcessors()) {
|
|
47
|
-
if (event === null) break;
|
|
48
|
-
event = await processor(event, eventHint);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return event?.contexts || {};
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const INTEGRATION_NAME = 'Anr';
|
|
55
|
-
|
|
56
|
-
const _anrIntegration = ((options = {}) => {
|
|
57
|
-
if (nodeVersion.NODE_VERSION.major < 16 || (nodeVersion.NODE_VERSION.major === 16 && nodeVersion.NODE_VERSION.minor < 17)) {
|
|
58
|
-
throw new Error('ANR detection requires Node 16.17.0 or later');
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
let worker;
|
|
62
|
-
let client;
|
|
63
|
-
|
|
64
|
-
// Hookup the scope fetch function to the global object so that it can be called from the worker thread via the
|
|
65
|
-
// debugger when it pauses
|
|
66
|
-
const gbl = globalWithScopeFetchFn();
|
|
67
|
-
gbl.__SENTRY_GET_SCOPES__ = getScopeData;
|
|
68
|
-
|
|
69
|
-
return {
|
|
70
|
-
name: INTEGRATION_NAME,
|
|
71
|
-
startWorker: () => {
|
|
72
|
-
if (worker) {
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (client) {
|
|
77
|
-
worker = _startWorker(client, options);
|
|
78
|
-
}
|
|
79
|
-
},
|
|
80
|
-
stopWorker: () => {
|
|
81
|
-
if (worker) {
|
|
82
|
-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
83
|
-
worker.then(stop => {
|
|
84
|
-
stop();
|
|
85
|
-
worker = undefined;
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
},
|
|
89
|
-
async setup(initClient) {
|
|
90
|
-
client = initClient;
|
|
91
|
-
|
|
92
|
-
if (options.captureStackTrace && (await debug.isDebuggerEnabled())) {
|
|
93
|
-
core.logger.warn('ANR captureStackTrace has been disabled because the debugger was already enabled');
|
|
94
|
-
options.captureStackTrace = false;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// setImmediate is used to ensure that all other integrations have had their setup called first.
|
|
98
|
-
// This allows us to call into all integrations to fetch the full context
|
|
99
|
-
setImmediate(() => this.startWorker());
|
|
100
|
-
},
|
|
101
|
-
} ;
|
|
102
|
-
}) ;
|
|
103
|
-
|
|
104
|
-
const anrIntegration = core.defineIntegration(_anrIntegration) ;
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Starts the ANR worker thread
|
|
108
|
-
*
|
|
109
|
-
* @returns A function to stop the worker
|
|
110
|
-
*/
|
|
111
|
-
async function _startWorker(
|
|
112
|
-
client,
|
|
113
|
-
integrationOptions,
|
|
114
|
-
) {
|
|
115
|
-
const dsn = client.getDsn();
|
|
116
|
-
|
|
117
|
-
if (!dsn) {
|
|
118
|
-
return () => {
|
|
119
|
-
//
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const contexts = await getContexts(client);
|
|
124
|
-
|
|
125
|
-
// These will not be accurate if sent later from the worker thread
|
|
126
|
-
delete contexts.app?.app_memory;
|
|
127
|
-
delete contexts.device?.free_memory;
|
|
128
|
-
|
|
129
|
-
const initOptions = client.getOptions();
|
|
130
|
-
|
|
131
|
-
const sdkMetadata = client.getSdkMetadata() || {};
|
|
132
|
-
if (sdkMetadata.sdk) {
|
|
133
|
-
sdkMetadata.sdk.integrations = initOptions.integrations.map(i => i.name);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
const options = {
|
|
137
|
-
debug: core.logger.isEnabled(),
|
|
138
|
-
dsn,
|
|
139
|
-
tunnel: initOptions.tunnel,
|
|
140
|
-
environment: initOptions.environment || 'production',
|
|
141
|
-
release: initOptions.release,
|
|
142
|
-
dist: initOptions.dist,
|
|
143
|
-
sdkMetadata,
|
|
144
|
-
appRootPath: integrationOptions.appRootPath,
|
|
145
|
-
pollInterval: integrationOptions.pollInterval || DEFAULT_INTERVAL,
|
|
146
|
-
anrThreshold: integrationOptions.anrThreshold || DEFAULT_HANG_THRESHOLD,
|
|
147
|
-
captureStackTrace: !!integrationOptions.captureStackTrace,
|
|
148
|
-
maxAnrEvents: integrationOptions.maxAnrEvents || 1,
|
|
149
|
-
staticTags: integrationOptions.staticTags || {},
|
|
150
|
-
contexts,
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
if (options.captureStackTrace) {
|
|
154
|
-
const inspector = await import('node:inspector');
|
|
155
|
-
if (!inspector.url()) {
|
|
156
|
-
inspector.open(0);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
const worker = new node_worker_threads.Worker(new URL(`data:application/javascript;base64,${base64WorkerScript}`), {
|
|
161
|
-
workerData: options,
|
|
162
|
-
// We don't want any Node args to be passed to the worker
|
|
163
|
-
execArgv: [],
|
|
164
|
-
env: { ...process.env, NODE_OPTIONS: undefined },
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
process.on('exit', () => {
|
|
168
|
-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
169
|
-
worker.terminate();
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
const timer = setInterval(() => {
|
|
173
|
-
try {
|
|
174
|
-
const currentSession = core.getIsolationScope().getSession();
|
|
175
|
-
// We need to copy the session object and remove the toJSON method so it can be sent to the worker
|
|
176
|
-
// serialized without making it a SerializedSession
|
|
177
|
-
const session = currentSession ? { ...currentSession, toJSON: undefined } : undefined;
|
|
178
|
-
// message the worker to tell it the main event loop is still running
|
|
179
|
-
worker.postMessage({ session, debugImages: core.getFilenameToDebugIdMap(initOptions.stackParser) });
|
|
180
|
-
} catch (_) {
|
|
181
|
-
//
|
|
182
|
-
}
|
|
183
|
-
}, options.pollInterval);
|
|
184
|
-
// Timer should not block exit
|
|
185
|
-
timer.unref();
|
|
186
|
-
|
|
187
|
-
worker.on('message', (msg) => {
|
|
188
|
-
if (msg === 'session-ended') {
|
|
189
|
-
log('ANR event sent from ANR worker. Clearing session in this thread.');
|
|
190
|
-
core.getIsolationScope().setSession(undefined);
|
|
191
|
-
}
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
worker.once('error', (err) => {
|
|
195
|
-
clearInterval(timer);
|
|
196
|
-
log('ANR worker error', err);
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
worker.once('exit', (code) => {
|
|
200
|
-
clearInterval(timer);
|
|
201
|
-
log('ANR worker exit', code);
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
// Ensure this thread can't block app exit
|
|
205
|
-
worker.unref();
|
|
206
|
-
|
|
207
|
-
return () => {
|
|
208
|
-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
209
|
-
worker.terminate();
|
|
210
|
-
clearInterval(timer);
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* Disables ANR detection for the duration of the callback
|
|
216
|
-
*/
|
|
217
|
-
function disableAnrDetectionForCallback(callback) {
|
|
218
|
-
const integration = core.getClient()?.getIntegrationByName(INTEGRATION_NAME) ;
|
|
219
|
-
|
|
220
|
-
if (!integration) {
|
|
221
|
-
return callback();
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
integration.stopWorker();
|
|
225
|
-
|
|
226
|
-
const result = callback();
|
|
227
|
-
if (isPromise(result)) {
|
|
228
|
-
return result.finally(() => integration.startWorker());
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
integration.startWorker();
|
|
232
|
-
return result;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
exports.anrIntegration = anrIntegration;
|
|
236
|
-
exports.base64WorkerScript = base64WorkerScript;
|
|
237
|
-
exports.disableAnrDetectionForCallback = disableAnrDetectionForCallback;
|
|
238
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../src/integrations/anr/index.ts"],"sourcesContent":["import { types } from 'node:util';\nimport { Worker } from 'node:worker_threads';\nimport type { Contexts, Event, EventHint, Integration, IntegrationFn, ScopeData } from '@sentry/core';\nimport {\n defineIntegration,\n getClient,\n getCurrentScope,\n getFilenameToDebugIdMap,\n getGlobalScope,\n getIsolationScope,\n GLOBAL_OBJ,\n logger,\n mergeScopeData,\n} from '@sentry/core';\nimport { NODE_VERSION } from '../../nodeVersion';\nimport type { NodeClient } from '../../sdk/client';\nimport { isDebuggerEnabled } from '../../utils/debug';\nimport type { AnrIntegrationOptions, WorkerStartData } from './common';\n\nconst { isPromise } = types;\n\n// This string is a placeholder that gets overwritten with the worker code.\nexport const base64WorkerScript = '###AnrWorkerScript###';\n\nconst DEFAULT_INTERVAL = 50;\nconst DEFAULT_HANG_THRESHOLD = 5000;\n\nfunction log(message: string, ...args: unknown[]): void {\n logger.log(`[ANR] ${message}`, ...args);\n}\n\nfunction globalWithScopeFetchFn(): typeof GLOBAL_OBJ & { __SENTRY_GET_SCOPES__?: () => ScopeData } {\n return GLOBAL_OBJ;\n}\n\n/** Fetches merged scope data */\nfunction getScopeData(): ScopeData {\n const scope = getGlobalScope().getScopeData();\n mergeScopeData(scope, getIsolationScope().getScopeData());\n mergeScopeData(scope, getCurrentScope().getScopeData());\n\n // We remove attachments because they likely won't serialize well as json\n scope.attachments = [];\n // We can't serialize event processor functions\n scope.eventProcessors = [];\n\n return scope;\n}\n\n/**\n * Gets contexts by calling all event processors. This shouldn't be called until all integrations are setup\n */\nasync function getContexts(client: NodeClient): Promise<Contexts> {\n let event: Event | null = { message: 'ANR' };\n const eventHint: EventHint = {};\n\n for (const processor of client.getEventProcessors()) {\n if (event === null) break;\n event = await processor(event, eventHint);\n }\n\n return event?.contexts || {};\n}\n\nconst INTEGRATION_NAME = 'Anr';\n\ntype AnrInternal = { startWorker: () => void; stopWorker: () => void };\n\nconst _anrIntegration = ((options: Partial<AnrIntegrationOptions> = {}) => {\n if (NODE_VERSION.major < 16 || (NODE_VERSION.major === 16 && NODE_VERSION.minor < 17)) {\n throw new Error('ANR detection requires Node 16.17.0 or later');\n }\n\n let worker: Promise<() => void> | undefined;\n let client: NodeClient | undefined;\n\n // Hookup the scope fetch function to the global object so that it can be called from the worker thread via the\n // debugger when it pauses\n const gbl = globalWithScopeFetchFn();\n gbl.__SENTRY_GET_SCOPES__ = getScopeData;\n\n return {\n name: INTEGRATION_NAME,\n startWorker: () => {\n if (worker) {\n return;\n }\n\n if (client) {\n worker = _startWorker(client, options);\n }\n },\n stopWorker: () => {\n if (worker) {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n worker.then(stop => {\n stop();\n worker = undefined;\n });\n }\n },\n async setup(initClient: NodeClient) {\n client = initClient;\n\n if (options.captureStackTrace && (await isDebuggerEnabled())) {\n logger.warn('ANR captureStackTrace has been disabled because the debugger was already enabled');\n options.captureStackTrace = false;\n }\n\n // setImmediate is used to ensure that all other integrations have had their setup called first.\n // This allows us to call into all integrations to fetch the full context\n setImmediate(() => this.startWorker());\n },\n } as Integration & AnrInternal;\n}) satisfies IntegrationFn;\n\ntype AnrReturn = (options?: Partial<AnrIntegrationOptions>) => Integration & AnrInternal;\n\nexport const anrIntegration = defineIntegration(_anrIntegration) as AnrReturn;\n\n/**\n * Starts the ANR worker thread\n *\n * @returns A function to stop the worker\n */\nasync function _startWorker(\n client: NodeClient,\n integrationOptions: Partial<AnrIntegrationOptions>,\n): Promise<() => void> {\n const dsn = client.getDsn();\n\n if (!dsn) {\n return () => {\n //\n };\n }\n\n const contexts = await getContexts(client);\n\n // These will not be accurate if sent later from the worker thread\n delete contexts.app?.app_memory;\n delete contexts.device?.free_memory;\n\n const initOptions = client.getOptions();\n\n const sdkMetadata = client.getSdkMetadata() || {};\n if (sdkMetadata.sdk) {\n sdkMetadata.sdk.integrations = initOptions.integrations.map(i => i.name);\n }\n\n const options: WorkerStartData = {\n debug: logger.isEnabled(),\n dsn,\n tunnel: initOptions.tunnel,\n environment: initOptions.environment || 'production',\n release: initOptions.release,\n dist: initOptions.dist,\n sdkMetadata,\n appRootPath: integrationOptions.appRootPath,\n pollInterval: integrationOptions.pollInterval || DEFAULT_INTERVAL,\n anrThreshold: integrationOptions.anrThreshold || DEFAULT_HANG_THRESHOLD,\n captureStackTrace: !!integrationOptions.captureStackTrace,\n maxAnrEvents: integrationOptions.maxAnrEvents || 1,\n staticTags: integrationOptions.staticTags || {},\n contexts,\n };\n\n if (options.captureStackTrace) {\n const inspector = await import('node:inspector');\n if (!inspector.url()) {\n inspector.open(0);\n }\n }\n\n const worker = new Worker(new URL(`data:application/javascript;base64,${base64WorkerScript}`), {\n workerData: options,\n // We don't want any Node args to be passed to the worker\n execArgv: [],\n env: { ...process.env, NODE_OPTIONS: undefined },\n });\n\n process.on('exit', () => {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n worker.terminate();\n });\n\n const timer = setInterval(() => {\n try {\n const currentSession = getIsolationScope().getSession();\n // We need to copy the session object and remove the toJSON method so it can be sent to the worker\n // serialized without making it a SerializedSession\n const session = currentSession ? { ...currentSession, toJSON: undefined } : undefined;\n // message the worker to tell it the main event loop is still running\n worker.postMessage({ session, debugImages: getFilenameToDebugIdMap(initOptions.stackParser) });\n } catch (_) {\n //\n }\n }, options.pollInterval);\n // Timer should not block exit\n timer.unref();\n\n worker.on('message', (msg: string) => {\n if (msg === 'session-ended') {\n log('ANR event sent from ANR worker. Clearing session in this thread.');\n getIsolationScope().setSession(undefined);\n }\n });\n\n worker.once('error', (err: Error) => {\n clearInterval(timer);\n log('ANR worker error', err);\n });\n\n worker.once('exit', (code: number) => {\n clearInterval(timer);\n log('ANR worker exit', code);\n });\n\n // Ensure this thread can't block app exit\n worker.unref();\n\n return () => {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n worker.terminate();\n clearInterval(timer);\n };\n}\n\nexport function disableAnrDetectionForCallback<T>(callback: () => T): T;\nexport function disableAnrDetectionForCallback<T>(callback: () => Promise<T>): Promise<T>;\n/**\n * Disables ANR detection for the duration of the callback\n */\nexport function disableAnrDetectionForCallback<T>(callback: () => T | Promise<T>): T | Promise<T> {\n const integration = getClient()?.getIntegrationByName(INTEGRATION_NAME) as AnrInternal | undefined;\n\n if (!integration) {\n return callback();\n }\n\n integration.stopWorker();\n\n const result = callback();\n if (isPromise(result)) {\n return result.finally(() => integration.startWorker());\n }\n\n integration.startWorker();\n return result;\n}\n"],"names":["types","logger","GLOBAL_OBJ","getGlobalScope","mergeScopeData","getIsolationScope","getCurrentScope","NODE_VERSION","isDebuggerEnabled","defineIntegration","Worker","getFilenameToDebugIdMap","getClient"],"mappings":"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"}
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
|
|
3
|
-
const diagnosticsChannel = require('node:diagnostics_channel');
|
|
4
|
-
const core = require('@sentry/core');
|
|
5
|
-
|
|
6
|
-
const INTEGRATION_NAME = 'ChildProcess';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Capture breadcrumbs and events for child processes and worker threads.
|
|
10
|
-
*/
|
|
11
|
-
const childProcessIntegration = core.defineIntegration((options = {}) => {
|
|
12
|
-
return {
|
|
13
|
-
name: INTEGRATION_NAME,
|
|
14
|
-
setup() {
|
|
15
|
-
diagnosticsChannel.channel('child_process').subscribe((event) => {
|
|
16
|
-
if (event && typeof event === 'object' && 'process' in event) {
|
|
17
|
-
captureChildProcessEvents(event.process , options);
|
|
18
|
-
}
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
diagnosticsChannel.channel('worker_threads').subscribe((event) => {
|
|
22
|
-
if (event && typeof event === 'object' && 'worker' in event) {
|
|
23
|
-
captureWorkerThreadEvents(event.worker , options);
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
-
},
|
|
27
|
-
};
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
function captureChildProcessEvents(child, options) {
|
|
31
|
-
let hasExited = false;
|
|
32
|
-
let data;
|
|
33
|
-
|
|
34
|
-
child
|
|
35
|
-
.on('spawn', () => {
|
|
36
|
-
// This is Sentry getting macOS OS context
|
|
37
|
-
if (child.spawnfile === '/usr/bin/sw_vers') {
|
|
38
|
-
hasExited = true;
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
data = { spawnfile: child.spawnfile };
|
|
43
|
-
if (options.includeChildProcessArgs) {
|
|
44
|
-
data.spawnargs = child.spawnargs;
|
|
45
|
-
}
|
|
46
|
-
})
|
|
47
|
-
.on('exit', code => {
|
|
48
|
-
if (!hasExited) {
|
|
49
|
-
hasExited = true;
|
|
50
|
-
|
|
51
|
-
// Only log for non-zero exit codes
|
|
52
|
-
if (code !== null && code !== 0) {
|
|
53
|
-
core.addBreadcrumb({
|
|
54
|
-
category: 'child_process',
|
|
55
|
-
message: `Child process exited with code '${code}'`,
|
|
56
|
-
level: code === 0 ? 'info' : 'warning',
|
|
57
|
-
data,
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
})
|
|
62
|
-
.on('error', error => {
|
|
63
|
-
if (!hasExited) {
|
|
64
|
-
hasExited = true;
|
|
65
|
-
|
|
66
|
-
core.addBreadcrumb({
|
|
67
|
-
category: 'child_process',
|
|
68
|
-
message: `Child process errored with '${error.message}'`,
|
|
69
|
-
level: 'error',
|
|
70
|
-
data,
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function captureWorkerThreadEvents(worker, options) {
|
|
77
|
-
let threadId;
|
|
78
|
-
|
|
79
|
-
worker
|
|
80
|
-
.on('online', () => {
|
|
81
|
-
threadId = worker.threadId;
|
|
82
|
-
})
|
|
83
|
-
.on('error', error => {
|
|
84
|
-
if (options.captureWorkerErrors !== false) {
|
|
85
|
-
core.captureException(error, {
|
|
86
|
-
mechanism: { type: 'instrument', handled: false, data: { threadId: String(threadId) } },
|
|
87
|
-
});
|
|
88
|
-
} else {
|
|
89
|
-
core.addBreadcrumb({
|
|
90
|
-
category: 'worker_thread',
|
|
91
|
-
message: `Worker thread errored with '${error.message}'`,
|
|
92
|
-
level: 'error',
|
|
93
|
-
data: { threadId },
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
exports.childProcessIntegration = childProcessIntegration;
|
|
100
|
-
//# sourceMappingURL=childProcess.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"childProcess.js","sources":["../../../src/integrations/childProcess.ts"],"sourcesContent":["import type { ChildProcess } from 'node:child_process';\nimport * as diagnosticsChannel from 'node:diagnostics_channel';\nimport type { Worker } from 'node:worker_threads';\nimport { addBreadcrumb, captureException, defineIntegration } from '@sentry/core';\n\ninterface Options {\n /**\n * Whether to include child process arguments in breadcrumbs data.\n *\n * @default false\n */\n includeChildProcessArgs?: boolean;\n\n /**\n * Whether to capture errors from worker threads.\n *\n * @default true\n */\n captureWorkerErrors?: boolean;\n}\n\nconst INTEGRATION_NAME = 'ChildProcess';\n\n/**\n * Capture breadcrumbs and events for child processes and worker threads.\n */\nexport const childProcessIntegration = defineIntegration((options: Options = {}) => {\n return {\n name: INTEGRATION_NAME,\n setup() {\n diagnosticsChannel.channel('child_process').subscribe((event: unknown) => {\n if (event && typeof event === 'object' && 'process' in event) {\n captureChildProcessEvents(event.process as ChildProcess, options);\n }\n });\n\n diagnosticsChannel.channel('worker_threads').subscribe((event: unknown) => {\n if (event && typeof event === 'object' && 'worker' in event) {\n captureWorkerThreadEvents(event.worker as Worker, options);\n }\n });\n },\n };\n});\n\nfunction captureChildProcessEvents(child: ChildProcess, options: Options): void {\n let hasExited = false;\n let data: Record<string, unknown> | undefined;\n\n child\n .on('spawn', () => {\n // This is Sentry getting macOS OS context\n if (child.spawnfile === '/usr/bin/sw_vers') {\n hasExited = true;\n return;\n }\n\n data = { spawnfile: child.spawnfile };\n if (options.includeChildProcessArgs) {\n data.spawnargs = child.spawnargs;\n }\n })\n .on('exit', code => {\n if (!hasExited) {\n hasExited = true;\n\n // Only log for non-zero exit codes\n if (code !== null && code !== 0) {\n addBreadcrumb({\n category: 'child_process',\n message: `Child process exited with code '${code}'`,\n level: code === 0 ? 'info' : 'warning',\n data,\n });\n }\n }\n })\n .on('error', error => {\n if (!hasExited) {\n hasExited = true;\n\n addBreadcrumb({\n category: 'child_process',\n message: `Child process errored with '${error.message}'`,\n level: 'error',\n data,\n });\n }\n });\n}\n\nfunction captureWorkerThreadEvents(worker: Worker, options: Options): void {\n let threadId: number | undefined;\n\n worker\n .on('online', () => {\n threadId = worker.threadId;\n })\n .on('error', error => {\n if (options.captureWorkerErrors !== false) {\n captureException(error, {\n mechanism: { type: 'instrument', handled: false, data: { threadId: String(threadId) } },\n });\n } else {\n addBreadcrumb({\n category: 'worker_thread',\n message: `Worker thread errored with '${error.message}'`,\n level: 'error',\n data: { threadId },\n });\n }\n });\n}\n"],"names":["defineIntegration","addBreadcrumb","captureException"],"mappings":"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"}
|