{"version":3,"file":"postgresjs.js","sources":["../../../../src/integrations/tracing/postgresjs.ts"],"sourcesContent":["// Instrumentation for https://github.com/porsager/postgres\n\nimport { context, trace } from '@opentelemetry/api';\nimport type { InstrumentationConfig } from '@opentelemetry/instrumentation';\nimport {\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n safeExecuteInTheMiddle,\n} from '@opentelemetry/instrumentation';\nimport { InstrumentationNodeModuleFile } from './InstrumentationNodeModuleFile';\nimport {\n ATTR_DB_OPERATION_NAME,\n ATTR_DB_QUERY_TEXT,\n ATTR_DB_RESPONSE_STATUS_CODE,\n ATTR_DB_SYSTEM_NAME,\n ATTR_ERROR_TYPE,\n} from '@opentelemetry/semantic-conventions';\nimport type { IntegrationFn, Span } from '@sentry/core';\nimport {\n debug,\n defineIntegration,\n instrumentPostgresJsSql,\n replaceExports,\n SDK_VERSION,\n SPAN_STATUS_ERROR,\n startSpanManual,\n} from '@sentry/core';\nimport { addOriginToSpan, generateInstrumentOnce } from '@sentry/node-core';\nimport { DEBUG_BUILD } from '../../debug-build';\n\nconst INTEGRATION_NAME = 'PostgresJs';\nconst SUPPORTED_VERSIONS = ['>=3.0.0 <4'];\nconst SQL_OPERATION_REGEX = /^(SELECT|INSERT|UPDATE|DELETE|CREATE|DROP|ALTER)/i;\n\ntype PostgresConnectionContext = {\n ATTR_DB_NAMESPACE?: string; // Database name\n ATTR_SERVER_ADDRESS?: string; // Hostname or IP address of the database server\n ATTR_SERVER_PORT?: string; // Port number of the database server\n};\n\n// Marker to track if a query was created from an instrumented sql instance\n// This prevents double-spanning when both wrapper and prototype patches are active\nconst QUERY_FROM_INSTRUMENTED_SQL = Symbol.for('sentry.query.from.instrumented.sql');\n\ntype PostgresJsInstrumentationConfig = InstrumentationConfig & {\n /**\n * Whether to require a parent span for the instrumentation.\n * If set to true, the instrumentation will only create spans if there is a parent span\n * available in the current scope.\n * @default true\n */\n requireParentSpan?: boolean;\n /**\n * Hook to modify the span before it is started.\n * This can be used to set additional attributes or modify the span in any way.\n */\n requestHook?: (span: Span, sanitizedSqlQuery: string, postgresConnectionContext?: PostgresConnectionContext) => void;\n};\n\nexport const instrumentPostgresJs = generateInstrumentOnce(\n INTEGRATION_NAME,\n (options?: PostgresJsInstrumentationConfig) =>\n new PostgresJsInstrumentation({\n requireParentSpan: options?.requireParentSpan ?? true,\n requestHook: options?.requestHook,\n }),\n);\n\n/**\n * Instrumentation for the [postgres](https://www.npmjs.com/package/postgres) library.\n * This instrumentation captures postgresjs queries and their attributes.\n *\n * Uses internal Sentry patching patterns to support both CommonJS and ESM environments.\n */\nexport class PostgresJsInstrumentation extends InstrumentationBase {\n public constructor(config: PostgresJsInstrumentationConfig) {\n super('sentry-postgres-js', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by patching the postgres module.\n * Uses two complementary approaches:\n * 1. Main function wrapper: instruments sql instances created AFTER instrumentation is set up (CJS + ESM)\n * 2. Query.prototype patch: fallback for sql instances created BEFORE instrumentation (CJS only)\n */\n public init(): InstrumentationNodeModuleDefinition {\n const module = new InstrumentationNodeModuleDefinition(\n 'postgres',\n SUPPORTED_VERSIONS,\n exports => {\n try {\n return this._patchPostgres(exports);\n } catch (e) {\n DEBUG_BUILD && debug.error('Failed to patch postgres module:', e);\n return exports;\n }\n },\n exports => exports,\n );\n\n // Add fallback Query.prototype patching for pre-existing sql instances (CJS only)\n // This catches queries from sql instances created before Sentry was initialized\n ['src', 'cf/src', 'cjs/src'].forEach(path => {\n module.files.push(\n new InstrumentationNodeModuleFile(\n `postgres/${path}/query.js`,\n SUPPORTED_VERSIONS,\n this._patchQueryPrototype.bind(this),\n this._unpatchQueryPrototype.bind(this),\n ),\n );\n });\n\n return module;\n }\n\n /**\n * Patches the postgres module by wrapping the main export function.\n * This intercepts the creation of sql instances and instruments them.\n */\n private _patchPostgres(exports: { [key: string]: unknown }): { [key: string]: unknown } {\n // In CJS: exports is the function itself\n // In ESM: exports.default is the function\n const isFunction = typeof exports === 'function';\n const Original = isFunction ? exports : exports.default;\n\n if (typeof Original !== 'function') {\n DEBUG_BUILD && debug.warn('postgres module does not export a function. Skipping instrumentation.');\n return exports;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n\n const WrappedPostgres = function (this: unknown, ...args: unknown[]): unknown {\n const sql = Reflect.construct(Original as (...args: unknown[]) => unknown, args);\n\n // Validate that construction succeeded and returned a valid function object\n if (!sql || typeof sql !== 'function') {\n DEBUG_BUILD && debug.warn('postgres() did not return a valid instance');\n return sql;\n }\n\n // Delegate to the portable instrumentation from @sentry/core\n const config = self.getConfig();\n return instrumentPostgresJsSql(sql, {\n requireParentSpan: config.requireParentSpan,\n requestHook: config.requestHook,\n });\n };\n\n Object.setPrototypeOf(WrappedPostgres, Original);\n Object.setPrototypeOf(WrappedPostgres.prototype, (Original as { prototype: object }).prototype);\n\n for (const key of Object.getOwnPropertyNames(Original)) {\n if (!['length', 'name', 'prototype'].includes(key)) {\n const descriptor = Object.getOwnPropertyDescriptor(Original, key);\n if (descriptor) {\n Object.defineProperty(WrappedPostgres, key, descriptor);\n }\n }\n }\n\n // For CJS: the exports object IS the function, so return the wrapped function\n // For ESM: replace the default export\n if (isFunction) {\n return WrappedPostgres as unknown as { [key: string]: unknown };\n } else {\n replaceExports(exports, 'default', WrappedPostgres);\n return exports;\n }\n }\n\n /**\n * Determines whether a span should be created based on the current context.\n * If `requireParentSpan` is set to true in the configuration, a span will\n * only be created if there is a parent span available.\n */\n private _shouldCreateSpans(): boolean {\n const config = this.getConfig();\n const hasParentSpan = trace.getSpan(context.active()) !== undefined;\n return hasParentSpan || !config.requireParentSpan;\n }\n\n /**\n * Extracts DB operation name from SQL query and sets it on the span.\n */\n private _setOperationName(span: Span, sanitizedQuery: string | undefined, command?: string): void {\n if (command) {\n span.setAttribute(ATTR_DB_OPERATION_NAME, command);\n return;\n }\n // Fallback: extract operation from the SQL query\n const operationMatch = sanitizedQuery?.match(SQL_OPERATION_REGEX);\n if (operationMatch?.[1]) {\n span.setAttribute(ATTR_DB_OPERATION_NAME, operationMatch[1].toUpperCase());\n }\n }\n\n /**\n * Reconstructs the full SQL query from template strings with PostgreSQL placeholders.\n *\n * For sql`SELECT * FROM users WHERE id = ${123} AND name = ${'foo'}`:\n * strings = [\"SELECT * FROM users WHERE id = \", \" AND name = \", \"\"]\n * returns: \"SELECT * FROM users WHERE id = $1 AND name = $2\"\n */\n private _reconstructQuery(strings: string[] | undefined): string | undefined {\n if (!strings?.length) {\n return undefined;\n }\n if (strings.length === 1) {\n return strings[0] || undefined;\n }\n // Join template parts with PostgreSQL placeholders ($1, $2, etc.)\n return strings.reduce((acc, str, i) => (i === 0 ? str : `${acc}$${i}${str}`), '');\n }\n\n /**\n * Sanitize SQL query as per the OTEL semantic conventions\n * https://opentelemetry.io/docs/specs/semconv/database/database-spans/#sanitization-of-dbquerytext\n *\n * PostgreSQL $n placeholders are preserved per OTEL spec - they're parameterized queries,\n * not sensitive literals. Only actual values (strings, numbers, booleans) are sanitized.\n */\n private _sanitizeSqlQuery(sqlQuery: string | undefined): string {\n if (!sqlQuery) {\n return 'Unknown SQL Query';\n }\n\n return (\n sqlQuery\n // Remove comments first (they may contain newlines and extra spaces)\n .replace(/--.*$/gm, '') // Single line comments (multiline mode)\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '') // Multi-line comments\n .replace(/;\\s*$/, '') // Remove trailing semicolons\n // Collapse whitespace to a single space (after removing comments)\n .replace(/\\s+/g, ' ')\n .trim() // Remove extra spaces and trim\n // Sanitize hex/binary literals before string literals\n .replace(/\\bX'[0-9A-Fa-f]*'/gi, '?') // Hex string literals\n .replace(/\\bB'[01]*'/gi, '?') // Binary string literals\n // Sanitize string literals (handles escaped quotes)\n .replace(/'(?:[^']|'')*'/g, '?')\n // Sanitize hex numbers\n .replace(/\\b0x[0-9A-Fa-f]+/gi, '?')\n // Sanitize boolean literals\n .replace(/\\b(?:TRUE|FALSE)\\b/gi, '?')\n // Sanitize numeric literals (preserve $n placeholders via negative lookbehind)\n .replace(/-?\\b\\d+\\.?\\d*[eE][+-]?\\d+\\b/g, '?') // Scientific notation\n .replace(/-?\\b\\d+\\.\\d+\\b/g, '?') // Decimals\n .replace(/-?\\.\\d+\\b/g, '?') // Decimals starting with dot\n .replace(/(? Promise) & {\n __sentry_original__?: (...args: unknown[]) => Promise;\n };\n };\n };\n }): typeof moduleExports {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n const originalHandle = moduleExports.Query.prototype.handle;\n\n moduleExports.Query.prototype.handle = async function (\n this: {\n resolve: unknown;\n reject: unknown;\n strings?: string[];\n },\n ...args: unknown[]\n ): Promise {\n // Skip if this query came from an instrumented sql instance (already handled by wrapper)\n if ((this as Record)[QUERY_FROM_INSTRUMENTED_SQL]) {\n return originalHandle.apply(this, args);\n }\n\n // Skip if we shouldn't create spans\n if (!self._shouldCreateSpans()) {\n return originalHandle.apply(this, args);\n }\n\n const fullQuery = self._reconstructQuery(this.strings);\n const sanitizedSqlQuery = self._sanitizeSqlQuery(fullQuery);\n\n return startSpanManual(\n {\n name: sanitizedSqlQuery || 'postgresjs.query',\n op: 'db',\n },\n (span: Span) => {\n addOriginToSpan(span, 'auto.db.postgresjs');\n\n span.setAttributes({\n [ATTR_DB_SYSTEM_NAME]: 'postgres',\n [ATTR_DB_QUERY_TEXT]: sanitizedSqlQuery,\n });\n\n // Note: No connection context available for pre-existing instances\n // because the sql instance wasn't created through our instrumented wrapper\n\n const config = self.getConfig();\n const { requestHook } = config;\n if (requestHook) {\n safeExecuteInTheMiddle(\n () => requestHook(span, sanitizedSqlQuery, undefined),\n e => {\n if (e) {\n span.setAttribute('sentry.hook.error', 'requestHook failed');\n DEBUG_BUILD && debug.error(`Error in requestHook for ${INTEGRATION_NAME} integration:`, e);\n }\n },\n true,\n );\n }\n\n // Wrap resolve to end span on success\n const originalResolve = this.resolve;\n this.resolve = new Proxy(originalResolve as (...args: unknown[]) => unknown, {\n apply: (resolveTarget, resolveThisArg, resolveArgs: [{ command?: string }]) => {\n try {\n self._setOperationName(span, sanitizedSqlQuery, resolveArgs?.[0]?.command);\n span.end();\n } catch (e) {\n DEBUG_BUILD && debug.error('Error ending span in resolve callback:', e);\n }\n return Reflect.apply(resolveTarget, resolveThisArg, resolveArgs);\n },\n });\n\n // Wrap reject to end span on error\n const originalReject = this.reject;\n this.reject = new Proxy(originalReject as (...args: unknown[]) => unknown, {\n apply: (rejectTarget, rejectThisArg, rejectArgs: { message?: string; code?: string; name?: string }[]) => {\n try {\n span.setStatus({\n code: SPAN_STATUS_ERROR,\n message: rejectArgs?.[0]?.message || 'unknown_error',\n });\n span.setAttribute(ATTR_DB_RESPONSE_STATUS_CODE, rejectArgs?.[0]?.code || 'unknown');\n span.setAttribute(ATTR_ERROR_TYPE, rejectArgs?.[0]?.name || 'unknown');\n self._setOperationName(span, sanitizedSqlQuery);\n span.end();\n } catch (e) {\n DEBUG_BUILD && debug.error('Error ending span in reject callback:', e);\n }\n return Reflect.apply(rejectTarget, rejectThisArg, rejectArgs);\n },\n });\n\n try {\n return originalHandle.apply(this, args);\n } catch (e) {\n span.setStatus({\n code: SPAN_STATUS_ERROR,\n message: e instanceof Error ? e.message : 'unknown_error',\n });\n span.end();\n throw e;\n }\n },\n );\n };\n\n // Store original for unpatch - must be set on the NEW patched function\n moduleExports.Query.prototype.handle.__sentry_original__ = originalHandle;\n\n return moduleExports;\n }\n\n /**\n * Restores the original Query.prototype.handle method.\n */\n private _unpatchQueryPrototype(moduleExports: {\n Query: {\n prototype: {\n handle: ((...args: unknown[]) => Promise) & {\n __sentry_original__?: (...args: unknown[]) => Promise;\n };\n };\n };\n }): typeof moduleExports {\n if (moduleExports.Query.prototype.handle.__sentry_original__) {\n moduleExports.Query.prototype.handle = moduleExports.Query.prototype.handle.__sentry_original__;\n }\n return moduleExports;\n }\n}\n\nconst _postgresJsIntegration = ((options?: PostgresJsInstrumentationConfig) => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentPostgresJs(options);\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [postgres](https://www.npmjs.com/package/postgres) library.\n *\n * For more information, see the [`postgresIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/postgres/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.postgresJsIntegration()],\n * });\n * ```\n */\n\nexport const postgresJsIntegration = defineIntegration(_postgresJsIntegration);\n"],"names":[],"mappings":";;;;;;;;AA8BA,MAAM,gBAAA,GAAmB,YAAA;AACzB,MAAM,kBAAA,GAAqB,CAAC,YAAY,CAAA;AACxC,MAAM,mBAAA,GAAsB,mDAAA;AAU5B,MAAM,2BAAA,mBAA8B,MAAA,CAAO,GAAA,CAAI,oCAAoC,CAAA;AAiB5E,MAAM,oBAAA,GAAuB,sBAAA;AAAA,EAClC,gBAAA;AAAA,EACA,CAAC,OAAA,KACC,IAAI,yBAAA,CAA0B;AAAA,IAC5B,iBAAA,EAAmB,SAAS,iBAAA,IAAqB,IAAA;AAAA,IACjD,aAAa,OAAA,EAAS;AAAA,GACvB;AACL;AAQO,MAAM,kCAAkC,mBAAA,CAAqD;AAAA,EAC3F,YAAY,MAAA,EAAyC;AAC1D,IAAA,KAAA,CAAM,oBAAA,EAAsB,aAAa,MAAM,CAAA;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,IAAA,GAA4C;AACjD,IAAA,MAAM,SAAS,IAAI,mCAAA;AAAA,MACjB,UAAA;AAAA,MACA,kBAAA;AAAA,MACA,CAAA,OAAA,KAAW;AACT,QAAA,IAAI;AACF,UAAA,OAAO,IAAA,CAAK,eAAe,OAAO,CAAA;AAAA,QACpC,SAAS,CAAA,EAAG;AACV,UAAA,WAAA,IAAe,KAAA,CAAM,KAAA,CAAM,kCAAA,EAAoC,CAAC,CAAA;AAChE,UAAA,OAAO,OAAA;AAAA,QACT;AAAA,MACF,CAAA;AAAA,MACA,CAAA,OAAA,KAAW;AAAA,KACb;AAIA,IAAA,CAAC,KAAA,EAAO,QAAA,EAAU,SAAS,CAAA,CAAE,QAAQ,CAAA,IAAA,KAAQ;AAC3C,MAAA,MAAA,CAAO,KAAA,CAAM,IAAA;AAAA,QACX,IAAI,6BAAA;AAAA,UACF,YAAY,IAAI,CAAA,SAAA,CAAA;AAAA,UAChB,kBAAA;AAAA,UACA,IAAA,CAAK,oBAAA,CAAqB,IAAA,CAAK,IAAI,CAAA;AAAA,UACnC,IAAA,CAAK,sBAAA,CAAuB,IAAA,CAAK,IAAI;AAAA;AACvC,OACF;AAAA,IACF,CAAC,CAAA;AAED,IAAA,OAAO,MAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,eAAe,OAAA,EAAiE;AAGtF,IAAA,MAAM,UAAA,GAAa,OAAO,OAAA,KAAY,UAAA;AACtC,IAAA,MAAM,QAAA,GAAW,UAAA,GAAa,OAAA,GAAU,OAAA,CAAQ,OAAA;AAEhD,IAAA,IAAI,OAAO,aAAa,UAAA,EAAY;AAClC,MAAA,WAAA,IAAe,KAAA,CAAM,KAAK,uEAAuE,CAAA;AACjG,MAAA,OAAO,OAAA;AAAA,IACT;AAGA,IAAA,MAAM,IAAA,GAAO,IAAA;AAEb,IAAA,MAAM,eAAA,GAAkB,YAA4B,IAAA,EAA0B;AAC5E,MAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,SAAA,CAAU,QAAA,EAA6C,IAAI,CAAA;AAG/E,MAAA,IAAI,CAAC,GAAA,IAAO,OAAO,GAAA,KAAQ,UAAA,EAAY;AACrC,QAAA,WAAA,IAAe,KAAA,CAAM,KAAK,4CAA4C,CAAA;AACtE,QAAA,OAAO,GAAA;AAAA,MACT;AAGA,MAAA,MAAM,MAAA,GAAS,KAAK,SAAA,EAAU;AAC9B,MAAA,OAAO,wBAAwB,GAAA,EAAK;AAAA,QAClC,mBAAmB,MAAA,CAAO,iBAAA;AAAA,QAC1B,aAAa,MAAA,CAAO;AAAA,OACrB,CAAA;AAAA,IACH,CAAA;AAEA,IAAA,MAAA,CAAO,cAAA,CAAe,iBAAiB,QAAQ,CAAA;AAC/C,IAAA,MAAA,CAAO,cAAA,CAAe,eAAA,CAAgB,SAAA,EAAY,QAAA,CAAmC,SAAS,CAAA;AAE9F,IAAA,KAAA,MAAW,GAAA,IAAO,MAAA,CAAO,mBAAA,CAAoB,QAAQ,CAAA,EAAG;AACtD,MAAA,IAAI,CAAC,CAAC,QAAA,EAAU,MAAA,EAAQ,WAAW,CAAA,CAAE,QAAA,CAAS,GAAG,CAAA,EAAG;AAClD,QAAA,MAAM,UAAA,GAAa,MAAA,CAAO,wBAAA,CAAyB,QAAA,EAAU,GAAG,CAAA;AAChE,QAAA,IAAI,UAAA,EAAY;AACd,UAAA,MAAA,CAAO,cAAA,CAAe,eAAA,EAAiB,GAAA,EAAK,UAAU,CAAA;AAAA,QACxD;AAAA,MACF;AAAA,IACF;AAIA,IAAA,IAAI,UAAA,EAAY;AACd,MAAA,OAAO,eAAA;AAAA,IACT,CAAA,MAAO;AACL,MAAA,cAAA,CAAe,OAAA,EAAS,WAAW,eAAe,CAAA;AAClD,MAAA,OAAO,OAAA;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,kBAAA,GAA8B;AACpC,IAAA,MAAM,MAAA,GAAS,KAAK,SAAA,EAAU;AAC9B,IAAA,MAAM,gBAAgB,KAAA,CAAM,OAAA,CAAQ,OAAA,CAAQ,MAAA,EAAQ,CAAA,KAAM,MAAA;AAC1D,IAAA,OAAO,aAAA,IAAiB,CAAC,MAAA,CAAO,iBAAA;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA,EAKQ,iBAAA,CAAkB,IAAA,EAAY,cAAA,EAAoC,OAAA,EAAwB;AAChG,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,IAAA,CAAK,YAAA,CAAa,wBAAwB,OAAO,CAAA;AACjD,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,cAAA,GAAiB,cAAA,EAAgB,KAAA,CAAM,mBAAmB,CAAA;AAChE,IAAA,IAAI,cAAA,GAAiB,CAAC,CAAA,EAAG;AACvB,MAAA,IAAA,CAAK,aAAa,sBAAA,EAAwB,cAAA,CAAe,CAAC,CAAA,CAAE,aAAa,CAAA;AAAA,IAC3E;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,kBAAkB,OAAA,EAAmD;AAC3E,IAAA,IAAI,CAAC,SAAS,MAAA,EAAQ;AACpB,MAAA,OAAO,MAAA;AAAA,IACT;AACA,IAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,MAAA,OAAO,OAAA,CAAQ,CAAC,CAAA,IAAK,MAAA;AAAA,IACvB;AAEA,IAAA,OAAO,QAAQ,MAAA,CAAO,CAAC,GAAA,EAAK,GAAA,EAAK,MAAO,CAAA,KAAM,CAAA,GAAI,GAAA,GAAM,CAAA,EAAG,GAAG,CAAA,CAAA,EAAI,CAAC,CAAA,EAAG,GAAG,IAAK,EAAE,CAAA;AAAA,EAClF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,kBAAkB,QAAA,EAAsC;AAC9D,IAAA,IAAI,CAAC,QAAA,EAAU;AACb,MAAA,OAAO,mBAAA;AAAA,IACT;AAEA,IAAA,OACE,QAAA,CAEG,OAAA,CAAQ,SAAA,EAAW,EAAE,CAAA,CACrB,OAAA,CAAQ,mBAAA,EAAqB,EAAE,CAAA,CAC/B,OAAA,CAAQ,OAAA,EAAS,EAAE,CAAA,CAEnB,OAAA,CAAQ,MAAA,EAAQ,GAAG,CAAA,CACnB,IAAA,EAAK,CAEL,OAAA,CAAQ,qBAAA,EAAuB,GAAG,CAAA,CAClC,OAAA,CAAQ,cAAA,EAAgB,GAAG,CAAA,CAE3B,OAAA,CAAQ,iBAAA,EAAmB,GAAG,CAAA,CAE9B,OAAA,CAAQ,oBAAA,EAAsB,GAAG,CAAA,CAEjC,OAAA,CAAQ,sBAAA,EAAwB,GAAG,CAAA,CAEnC,OAAA,CAAQ,8BAAA,EAAgC,GAAG,CAAA,CAC3C,OAAA,CAAQ,iBAAA,EAAmB,GAAG,CAAA,CAC9B,OAAA,CAAQ,YAAA,EAAc,GAAG,CAAA,CACzB,OAAA,CAAQ,mBAAA,EAAqB,GAAG,CAAA,CAEhC,OAAA,CAAQ,uCAAA,EAAyC,QAAQ,CAAA,CACzD,OAAA,CAAQ,+CAA+C,SAAS,CAAA;AAAA,EAEvE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,qBAAqB,aAAA,EAQJ;AAEvB,IAAA,MAAM,IAAA,GAAO,IAAA;AACb,IAAA,MAAM,cAAA,GAAiB,aAAA,CAAc,KAAA,CAAM,SAAA,CAAU,MAAA;AAErD,IAAA,aAAA,CAAc,KAAA,CAAM,SAAA,CAAU,MAAA,GAAS,eAAA,GAMlC,IAAA,EACe;AAElB,MAAA,IAAK,IAAA,CAAiC,2BAA2B,CAAA,EAAG;AAClE,QAAA,OAAO,cAAA,CAAe,KAAA,CAAM,IAAA,EAAM,IAAI,CAAA;AAAA,MACxC;AAGA,MAAA,IAAI,CAAC,IAAA,CAAK,kBAAA,EAAmB,EAAG;AAC9B,QAAA,OAAO,cAAA,CAAe,KAAA,CAAM,IAAA,EAAM,IAAI,CAAA;AAAA,MACxC;AAEA,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,iBAAA,CAAkB,IAAA,CAAK,OAAO,CAAA;AACrD,MAAA,MAAM,iBAAA,GAAoB,IAAA,CAAK,iBAAA,CAAkB,SAAS,CAAA;AAE1D,MAAA,OAAO,eAAA;AAAA,QACL;AAAA,UACE,MAAM,iBAAA,IAAqB,kBAAA;AAAA,UAC3B,EAAA,EAAI;AAAA,SACN;AAAA,QACA,CAAC,IAAA,KAAe;AACd,UAAA,eAAA,CAAgB,MAAM,oBAAoB,CAAA;AAE1C,UAAA,IAAA,CAAK,aAAA,CAAc;AAAA,YACjB,CAAC,mBAAmB,GAAG,UAAA;AAAA,YACvB,CAAC,kBAAkB,GAAG;AAAA,WACvB,CAAA;AAKD,UAAA,MAAM,MAAA,GAAS,KAAK,SAAA,EAAU;AAC9B,UAAA,MAAM,EAAE,aAAY,GAAI,MAAA;AACxB,UAAA,IAAI,WAAA,EAAa;AACf,YAAA,sBAAA;AAAA,cACE,MAAM,WAAA,CAAY,IAAA,EAAM,iBAAA,EAAmB,MAAS,CAAA;AAAA,cACpD,CAAA,CAAA,KAAK;AACH,gBAAA,IAAI,CAAA,EAAG;AACL,kBAAA,IAAA,CAAK,YAAA,CAAa,qBAAqB,oBAAoB,CAAA;AAC3D,kBAAA,WAAA,IAAe,KAAA,CAAM,KAAA,CAAM,CAAA,yBAAA,EAA4B,gBAAgB,iBAAiB,CAAC,CAAA;AAAA,gBAC3F;AAAA,cACF,CAAA;AAAA,cACA;AAAA,aACF;AAAA,UACF;AAGA,UAAA,MAAM,kBAAkB,IAAA,CAAK,OAAA;AAC7B,UAAA,IAAA,CAAK,OAAA,GAAU,IAAI,KAAA,CAAM,eAAA,EAAoD;AAAA,YAC3E,KAAA,EAAO,CAAC,aAAA,EAAe,cAAA,EAAgB,WAAA,KAAwC;AAC7E,cAAA,IAAI;AACF,gBAAA,IAAA,CAAK,kBAAkB,IAAA,EAAM,iBAAA,EAAmB,WAAA,GAAc,CAAC,GAAG,OAAO,CAAA;AACzE,gBAAA,IAAA,CAAK,GAAA,EAAI;AAAA,cACX,SAAS,CAAA,EAAG;AACV,gBAAA,WAAA,IAAe,KAAA,CAAM,KAAA,CAAM,wCAAA,EAA0C,CAAC,CAAA;AAAA,cACxE;AACA,cAAA,OAAO,OAAA,CAAQ,KAAA,CAAM,aAAA,EAAe,cAAA,EAAgB,WAAW,CAAA;AAAA,YACjE;AAAA,WACD,CAAA;AAGD,UAAA,MAAM,iBAAiB,IAAA,CAAK,MAAA;AAC5B,UAAA,IAAA,CAAK,MAAA,GAAS,IAAI,KAAA,CAAM,cAAA,EAAmD;AAAA,YACzE,KAAA,EAAO,CAAC,YAAA,EAAc,aAAA,EAAe,UAAA,KAAqE;AACxG,cAAA,IAAI;AACF,gBAAA,IAAA,CAAK,SAAA,CAAU;AAAA,kBACb,IAAA,EAAM,iBAAA;AAAA,kBACN,OAAA,EAAS,UAAA,GAAa,CAAC,CAAA,EAAG,OAAA,IAAW;AAAA,iBACtC,CAAA;AACD,gBAAA,IAAA,CAAK,aAAa,4BAAA,EAA8B,UAAA,GAAa,CAAC,CAAA,EAAG,QAAQ,SAAS,CAAA;AAClF,gBAAA,IAAA,CAAK,aAAa,eAAA,EAAiB,UAAA,GAAa,CAAC,CAAA,EAAG,QAAQ,SAAS,CAAA;AACrE,gBAAA,IAAA,CAAK,iBAAA,CAAkB,MAAM,iBAAiB,CAAA;AAC9C,gBAAA,IAAA,CAAK,GAAA,EAAI;AAAA,cACX,SAAS,CAAA,EAAG;AACV,gBAAA,WAAA,IAAe,KAAA,CAAM,KAAA,CAAM,uCAAA,EAAyC,CAAC,CAAA;AAAA,cACvE;AACA,cAAA,OAAO,OAAA,CAAQ,KAAA,CAAM,YAAA,EAAc,aAAA,EAAe,UAAU,CAAA;AAAA,YAC9D;AAAA,WACD,CAAA;AAED,UAAA,IAAI;AACF,YAAA,OAAO,cAAA,CAAe,KAAA,CAAM,IAAA,EAAM,IAAI,CAAA;AAAA,UACxC,SAAS,CAAA,EAAG;AACV,YAAA,IAAA,CAAK,SAAA,CAAU;AAAA,cACb,IAAA,EAAM,iBAAA;AAAA,cACN,OAAA,EAAS,CAAA,YAAa,KAAA,GAAQ,CAAA,CAAE,OAAA,GAAU;AAAA,aAC3C,CAAA;AACD,YAAA,IAAA,CAAK,GAAA,EAAI;AACT,YAAA,MAAM,CAAA;AAAA,UACR;AAAA,QACF;AAAA,OACF;AAAA,IACF,CAAA;AAGA,IAAA,aAAA,CAAc,KAAA,CAAM,SAAA,CAAU,MAAA,CAAO,mBAAA,GAAsB,cAAA;AAE3D,IAAA,OAAO,aAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,uBAAuB,aAAA,EAQN;AACvB,IAAA,IAAI,aAAA,CAAc,KAAA,CAAM,SAAA,CAAU,MAAA,CAAO,mBAAA,EAAqB;AAC5D,MAAA,aAAA,CAAc,MAAM,SAAA,CAAU,MAAA,GAAS,aAAA,CAAc,KAAA,CAAM,UAAU,MAAA,CAAO,mBAAA;AAAA,IAC9E;AACA,IAAA,OAAO,aAAA;AAAA,EACT;AACF;AAEA,MAAM,sBAAA,IAA0B,CAAC,OAAA,KAA8C;AAC7E,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,gBAAA;AAAA,IACN,SAAA,GAAY;AACV,MAAA,oBAAA,CAAqB,OAAO,CAAA;AAAA,IAC9B;AAAA,GACF;AACF,CAAA,CAAA;AAiBO,MAAM,qBAAA,GAAwB,kBAAkB,sBAAsB;;;;"}