Files
Shifted/node_modules/@mswjs/interceptors/lib/node/ClientRequest-2rDe54Ui.cjs.map
2026-02-10 01:14:19 +00:00

1 line
80 KiB
Plaintext

{"version":3,"file":"ClientRequest-2rDe54Ui.cjs","names":["normalized: NormalizedSocketWriteArgs","net","options: MockSocketOptions","headers","inferredRawHeaders: RawHeaders","HTTPParser","FetchResponse","Readable","createRequestId","INTERNAL_REQUEST_ID_HEADER_NAME","HTTPParser","writeArgs: NormalizedSocketWriteArgs | undefined","isPropertyAccessible","ServerResponse","IncomingMessage","STATUS_CODES","net","http","https","logger","Logger","Agent","logger","Logger","Logger","url: URL","options: ResolvedRequestOptions","callback: HttpRequestCallback | undefined","url","URL","isObject","httpsGlobalAgent","httpGlobalAgent","Interceptor","RequestController","handleRequest","emitAsync","http","https"],"sources":["../../src/interceptors/Socket/utils/normalizeSocketWriteArgs.ts","../../src/interceptors/Socket/MockSocket.ts","../../src/interceptors/Socket/utils/baseUrlFromConnectionOptions.ts","../../src/interceptors/ClientRequest/utils/recordRawHeaders.ts","../../src/interceptors/ClientRequest/utils/parserUtils.ts","../../src/interceptors/ClientRequest/MockHttpSocket.ts","../../src/interceptors/ClientRequest/agents.ts","../../src/utils/getUrlByRequestOptions.ts","../../src/utils/cloneObject.ts","../../src/interceptors/ClientRequest/utils/normalizeClientRequestArgs.ts","../../src/interceptors/ClientRequest/index.ts"],"sourcesContent":["export type WriteCallback = (error?: Error | null) => void\n\nexport type WriteArgs =\n | [chunk: unknown, callback?: WriteCallback]\n | [chunk: unknown, encoding: BufferEncoding, callback?: WriteCallback]\n\nexport type NormalizedSocketWriteArgs = [\n chunk: any,\n encoding?: BufferEncoding,\n callback?: WriteCallback,\n]\n\n/**\n * Normalizes the arguments provided to the `Writable.prototype.write()`\n * and `Writable.prototype.end()`.\n */\nexport function normalizeSocketWriteArgs(\n args: WriteArgs\n): NormalizedSocketWriteArgs {\n const normalized: NormalizedSocketWriteArgs = [args[0], undefined, undefined]\n\n if (typeof args[1] === 'string') {\n normalized[1] = args[1]\n } else if (typeof args[1] === 'function') {\n normalized[2] = args[1]\n }\n\n if (typeof args[2] === 'function') {\n normalized[2] = args[2]\n }\n\n return normalized\n}\n","import net from 'node:net'\nimport {\n normalizeSocketWriteArgs,\n type WriteArgs,\n type WriteCallback,\n} from './utils/normalizeSocketWriteArgs'\n\nexport interface MockSocketOptions {\n write: (\n chunk: Buffer | string,\n encoding: BufferEncoding | undefined,\n callback?: WriteCallback\n ) => void\n\n read: (chunk: Buffer, encoding: BufferEncoding | undefined) => void\n}\n\nexport class MockSocket extends net.Socket {\n public connecting: boolean\n\n constructor(protected readonly options: MockSocketOptions) {\n super()\n this.connecting = false\n this.connect()\n\n this._final = (callback) => {\n callback(null)\n }\n }\n\n public connect() {\n // The connection will remain pending until\n // the consumer decides to handle it.\n this.connecting = true\n return this\n }\n\n public write(...args: Array<unknown>): boolean {\n const [chunk, encoding, callback] = normalizeSocketWriteArgs(\n args as WriteArgs\n )\n this.options.write(chunk, encoding, callback)\n return true\n }\n\n public end(...args: Array<unknown>) {\n const [chunk, encoding, callback] = normalizeSocketWriteArgs(\n args as WriteArgs\n )\n this.options.write(chunk, encoding, callback)\n return super.end.apply(this, args as any)\n }\n\n public push(chunk: any, encoding?: BufferEncoding): boolean {\n this.options.read(chunk, encoding)\n return super.push(chunk, encoding)\n }\n}\n","export function baseUrlFromConnectionOptions(options: any): URL {\n if ('href' in options) {\n return new URL(options.href)\n }\n\n const protocol = options.port === 443 ? 'https:' : 'http:'\n const host = options.host\n\n const url = new URL(`${protocol}//${host}`)\n\n if (options.port) {\n url.port = options.port.toString()\n }\n\n if (options.path) {\n url.pathname = options.path\n }\n\n if (options.auth) {\n const [username, password] = options.auth.split(':')\n url.username = username\n url.password = password\n }\n\n return url\n}\n","type HeaderTuple = [string, string]\ntype RawHeaders = Array<HeaderTuple>\ntype SetHeaderBehavior = 'set' | 'append'\n\nconst kRawHeaders = Symbol('kRawHeaders')\nconst kRestorePatches = Symbol('kRestorePatches')\n\nfunction recordRawHeader(\n headers: Headers,\n args: HeaderTuple,\n behavior: SetHeaderBehavior\n) {\n ensureRawHeadersSymbol(headers, [])\n const rawHeaders = Reflect.get(headers, kRawHeaders) as RawHeaders\n\n if (behavior === 'set') {\n // When recording a set header, ensure we remove any matching existing headers.\n for (let index = rawHeaders.length - 1; index >= 0; index--) {\n if (rawHeaders[index][0].toLowerCase() === args[0].toLowerCase()) {\n rawHeaders.splice(index, 1)\n }\n }\n }\n\n rawHeaders.push(args)\n}\n\n/**\n * Define the raw headers symbol on the given `Headers` instance.\n * If the symbol already exists, this function does nothing.\n */\nfunction ensureRawHeadersSymbol(\n headers: Headers,\n rawHeaders: RawHeaders\n): void {\n if (Reflect.has(headers, kRawHeaders)) {\n return\n }\n\n defineRawHeadersSymbol(headers, rawHeaders)\n}\n\n/**\n * Define the raw headers symbol on the given `Headers` instance.\n * If the symbol already exists, it gets overridden.\n */\nfunction defineRawHeadersSymbol(headers: Headers, rawHeaders: RawHeaders) {\n Object.defineProperty(headers, kRawHeaders, {\n value: rawHeaders,\n enumerable: false,\n // Mark the symbol as configurable so its value can be overridden.\n // Overrides happen when merging raw headers from multiple sources.\n // E.g. new Request(new Request(url, { headers }), { headers })\n configurable: true,\n })\n}\n\n/**\n * Patch the global `Headers` class to store raw headers.\n * This is for compatibility with `IncomingMessage.prototype.rawHeaders`.\n *\n * @note Node.js has their own raw headers symbol but it\n * only records the first header name in case of multi-value headers.\n * Any other headers are normalized before comparing. This makes it\n * incompatible with the `rawHeaders` format.\n *\n * let h = new Headers()\n * h.append('X-Custom', 'one')\n * h.append('x-custom', 'two')\n * h[Symbol('headers map')] // Map { 'X-Custom' => 'one, two' }\n */\nexport function recordRawFetchHeaders() {\n // Prevent patching the Headers prototype multiple times.\n if (Reflect.get(Headers, kRestorePatches)) {\n return Reflect.get(Headers, kRestorePatches)\n }\n\n const {\n Headers: OriginalHeaders,\n Request: OriginalRequest,\n Response: OriginalResponse,\n } = globalThis\n const { set, append, delete: headersDeleteMethod } = Headers.prototype\n\n Object.defineProperty(Headers, kRestorePatches, {\n value: () => {\n Headers.prototype.set = set\n Headers.prototype.append = append\n Headers.prototype.delete = headersDeleteMethod\n globalThis.Headers = OriginalHeaders\n\n globalThis.Request = OriginalRequest\n globalThis.Response = OriginalResponse\n\n Reflect.deleteProperty(Headers, kRestorePatches)\n },\n enumerable: false,\n /**\n * @note Mark this property as configurable\n * so we can delete it using `Reflect.delete` during cleanup.\n */\n configurable: true,\n })\n\n Object.defineProperty(globalThis, 'Headers', {\n enumerable: true,\n writable: true,\n value: new Proxy(Headers, {\n construct(target, args, newTarget) {\n const headersInit = args[0] || []\n\n if (\n headersInit instanceof Headers &&\n Reflect.has(headersInit, kRawHeaders)\n ) {\n const headers = Reflect.construct(\n target,\n [Reflect.get(headersInit, kRawHeaders)],\n newTarget\n )\n ensureRawHeadersSymbol(headers, [\n /**\n * @note Spread the retrieved headers to clone them.\n * This prevents multiple Headers instances from pointing\n * at the same internal \"rawHeaders\" array.\n */\n ...Reflect.get(headersInit, kRawHeaders),\n ])\n return headers\n }\n\n const headers = Reflect.construct(target, args, newTarget)\n\n // Request/Response constructors will set the symbol\n // upon creating a new instance, using the raw developer\n // input as the raw headers. Skip the symbol altogether\n // in those cases because the input to Headers will be normalized.\n if (!Reflect.has(headers, kRawHeaders)) {\n const rawHeadersInit = Array.isArray(headersInit)\n ? headersInit\n : Object.entries(headersInit)\n ensureRawHeadersSymbol(headers, rawHeadersInit)\n }\n\n return headers\n },\n }),\n })\n\n Headers.prototype.set = new Proxy(Headers.prototype.set, {\n apply(target, thisArg, args: HeaderTuple) {\n recordRawHeader(thisArg, args, 'set')\n return Reflect.apply(target, thisArg, args)\n },\n })\n\n Headers.prototype.append = new Proxy(Headers.prototype.append, {\n apply(target, thisArg, args: HeaderTuple) {\n recordRawHeader(thisArg, args, 'append')\n return Reflect.apply(target, thisArg, args)\n },\n })\n\n Headers.prototype.delete = new Proxy(Headers.prototype.delete, {\n apply(target, thisArg, args: [string]) {\n const rawHeaders = Reflect.get(thisArg, kRawHeaders) as RawHeaders\n\n if (rawHeaders) {\n for (let index = rawHeaders.length - 1; index >= 0; index--) {\n if (rawHeaders[index][0].toLowerCase() === args[0].toLowerCase()) {\n rawHeaders.splice(index, 1)\n }\n }\n }\n\n return Reflect.apply(target, thisArg, args)\n },\n })\n\n Object.defineProperty(globalThis, 'Request', {\n enumerable: true,\n writable: true,\n value: new Proxy(Request, {\n construct(target, args, newTarget) {\n const request = Reflect.construct(target, args, newTarget)\n const inferredRawHeaders: RawHeaders = []\n\n // Infer raw headers from a `Request` instance used as init.\n if (typeof args[0] === 'object' && args[0].headers != null) {\n inferredRawHeaders.push(...inferRawHeaders(args[0].headers))\n }\n\n // Infer raw headers from the \"headers\" init argument.\n if (typeof args[1] === 'object' && args[1].headers != null) {\n inferredRawHeaders.push(...inferRawHeaders(args[1].headers))\n }\n\n if (inferredRawHeaders.length > 0) {\n ensureRawHeadersSymbol(request.headers, inferredRawHeaders)\n }\n\n return request\n },\n }),\n })\n\n Object.defineProperty(globalThis, 'Response', {\n enumerable: true,\n writable: true,\n value: new Proxy(Response, {\n construct(target, args, newTarget) {\n const response = Reflect.construct(target, args, newTarget)\n\n if (typeof args[1] === 'object' && args[1].headers != null) {\n ensureRawHeadersSymbol(\n response.headers,\n inferRawHeaders(args[1].headers)\n )\n }\n\n return response\n },\n }),\n })\n}\n\nexport function restoreHeadersPrototype() {\n if (!Reflect.get(Headers, kRestorePatches)) {\n return\n }\n\n Reflect.get(Headers, kRestorePatches)()\n}\n\nexport function getRawFetchHeaders(headers: Headers): RawHeaders {\n // If the raw headers recording failed for some reason,\n // use the normalized header entries instead.\n if (!Reflect.has(headers, kRawHeaders)) {\n return Array.from(headers.entries())\n }\n\n const rawHeaders = Reflect.get(headers, kRawHeaders) as RawHeaders\n return rawHeaders.length > 0 ? rawHeaders : Array.from(headers.entries())\n}\n\n/**\n * Infers the raw headers from the given `HeadersInit` provided\n * to the Request/Response constructor.\n *\n * If the `init.headers` is a Headers instance, use it directly.\n * That means the headers were created standalone and already have\n * the raw headers stored.\n * If the `init.headers` is a HeadersInit, create a new Headers\n * instance out of it.\n */\nfunction inferRawHeaders(headers: HeadersInit): RawHeaders {\n if (headers instanceof Headers) {\n return Reflect.get(headers, kRawHeaders) || []\n }\n\n return Reflect.get(new Headers(headers), kRawHeaders)\n}\n","import type { Socket } from 'node:net'\nimport { HTTPParser } from '_http_common'\n\n/**\n * @see https://github.com/nodejs/node/blob/f3adc11e37b8bfaaa026ea85c1cf22e3a0e29ae9/lib/_http_common.js#L180\n */\nexport function freeParser(parser: HTTPParser<any>, socket?: Socket): void {\n if (parser._consumed) {\n parser.unconsume()\n }\n\n parser._headers = []\n parser._url = ''\n parser.socket = null\n parser.incoming = null\n parser.outgoing = null\n parser.maxHeaderPairs = 2000\n parser._consumed = false\n parser.onIncoming = null\n\n parser[HTTPParser.kOnHeaders] = null\n parser[HTTPParser.kOnHeadersComplete] = null\n parser[HTTPParser.kOnMessageBegin] = null\n parser[HTTPParser.kOnMessageComplete] = null\n parser[HTTPParser.kOnBody] = null\n parser[HTTPParser.kOnExecute] = null\n parser[HTTPParser.kOnTimeout] = null\n\n parser.remove()\n parser.free()\n\n if (socket) {\n /**\n * @note Unassigning the socket's parser will fail this assertion\n * if there's still some data being processed on the socket:\n * @see https://github.com/nodejs/node/blob/4e1f39b678b37017ac9baa0971e3aeecd3b67b51/lib/_http_client.js#L613\n */\n if (socket.destroyed) {\n // @ts-expect-error Node.js internals.\n socket.parser = null\n } else {\n socket.once('end', () => {\n // @ts-expect-error Node.js internals.\n socket.parser = null\n })\n }\n }\n}\n","import net from 'node:net'\nimport {\n type HeadersCallback,\n HTTPParser,\n type RequestHeadersCompleteCallback,\n type ResponseHeadersCompleteCallback,\n} from '_http_common'\nimport { STATUS_CODES, IncomingMessage, ServerResponse } from 'node:http'\nimport { Readable } from 'node:stream'\nimport { invariant } from 'outvariant'\nimport { INTERNAL_REQUEST_ID_HEADER_NAME } from '../../Interceptor'\nimport { MockSocket } from '../Socket/MockSocket'\nimport type { NormalizedSocketWriteArgs } from '../Socket/utils/normalizeSocketWriteArgs'\nimport { isPropertyAccessible } from '../../utils/isPropertyAccessible'\nimport { baseUrlFromConnectionOptions } from '../Socket/utils/baseUrlFromConnectionOptions'\nimport { createRequestId } from '../../createRequestId'\nimport { getRawFetchHeaders } from './utils/recordRawHeaders'\nimport { FetchResponse } from '../../utils/fetchUtils'\nimport { setRawRequest } from '../../getRawRequest'\nimport { setRawRequestBodyStream } from '../../utils/node'\nimport { freeParser } from './utils/parserUtils'\n\ntype HttpConnectionOptions = any\n\nexport type MockHttpSocketRequestCallback = (args: {\n requestId: string\n request: Request\n socket: MockHttpSocket\n}) => void\n\nexport type MockHttpSocketResponseCallback = (args: {\n requestId: string\n request: Request\n response: Response\n isMockedResponse: boolean\n socket: MockHttpSocket\n}) => Promise<void>\n\ninterface MockHttpSocketOptions {\n connectionOptions: HttpConnectionOptions\n createConnection: () => net.Socket\n onRequest: MockHttpSocketRequestCallback\n onResponse: MockHttpSocketResponseCallback\n}\n\nexport const kRequestId = Symbol('kRequestId')\n\nexport class MockHttpSocket extends MockSocket {\n private connectionOptions: HttpConnectionOptions\n private createConnection: () => net.Socket\n private baseUrl: URL\n\n private onRequest: MockHttpSocketRequestCallback\n private onResponse: MockHttpSocketResponseCallback\n private responseListenersPromise?: Promise<void>\n\n private requestRawHeadersBuffer: Array<string> = []\n private responseRawHeadersBuffer: Array<string> = []\n private writeBuffer: Array<NormalizedSocketWriteArgs> = []\n private request?: Request\n private requestParser: HTTPParser<0>\n private requestStream?: Readable\n private shouldKeepAlive?: boolean\n\n private socketState: 'unknown' | 'mock' | 'passthrough' = 'unknown'\n private responseParser: HTTPParser<1>\n private responseStream?: Readable\n private originalSocket?: net.Socket\n\n constructor(options: MockHttpSocketOptions) {\n super({\n write: (chunk, encoding, callback) => {\n // Buffer the writes so they can be flushed in case of the original connection\n // and when reading the request body in the interceptor. If the connection has\n // been established, no need to buffer the chunks anymore, they will be forwarded.\n if (this.socketState !== 'passthrough') {\n this.writeBuffer.push([chunk, encoding, callback])\n }\n\n if (chunk) {\n /**\n * Forward any writes to the mock socket to the underlying original socket.\n * This ensures functional duplex connections, like WebSocket.\n * @see https://github.com/mswjs/interceptors/issues/682\n */\n if (this.socketState === 'passthrough') {\n this.originalSocket?.write(chunk, encoding, callback)\n }\n\n this.requestParser.execute(\n Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, encoding)\n )\n }\n },\n read: (chunk) => {\n if (chunk !== null) {\n /**\n * @todo We need to free the parser if the connection has been\n * upgraded to a non-HTTP protocol. It won't be able to parse data\n * from that point onward anyway. No need to keep it in memory.\n */\n this.responseParser.execute(\n Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)\n )\n }\n },\n })\n\n this.connectionOptions = options.connectionOptions\n this.createConnection = options.createConnection\n this.onRequest = options.onRequest\n this.onResponse = options.onResponse\n\n this.baseUrl = baseUrlFromConnectionOptions(this.connectionOptions)\n\n // Request parser.\n this.requestParser = new HTTPParser()\n this.requestParser.initialize(HTTPParser.REQUEST, {})\n this.requestParser[HTTPParser.kOnHeaders] = this.onRequestHeaders.bind(this)\n this.requestParser[HTTPParser.kOnHeadersComplete] =\n this.onRequestStart.bind(this)\n this.requestParser[HTTPParser.kOnBody] = this.onRequestBody.bind(this)\n this.requestParser[HTTPParser.kOnMessageComplete] =\n this.onRequestEnd.bind(this)\n\n // Response parser.\n this.responseParser = new HTTPParser()\n this.responseParser.initialize(HTTPParser.RESPONSE, {})\n this.responseParser[HTTPParser.kOnHeaders] =\n this.onResponseHeaders.bind(this)\n this.responseParser[HTTPParser.kOnHeadersComplete] =\n this.onResponseStart.bind(this)\n this.responseParser[HTTPParser.kOnBody] = this.onResponseBody.bind(this)\n this.responseParser[HTTPParser.kOnMessageComplete] =\n this.onResponseEnd.bind(this)\n\n // Once the socket is finished, nothing can write to it\n // anymore. It has also flushed any buffered chunks.\n this.once('finish', () => freeParser(this.requestParser, this))\n\n if (this.baseUrl.protocol === 'https:') {\n Reflect.set(this, 'encrypted', true)\n // The server certificate is not the same as a CA\n // passed to the TLS socket connection options.\n Reflect.set(this, 'authorized', false)\n Reflect.set(this, 'getProtocol', () => 'TLSv1.3')\n Reflect.set(this, 'getSession', () => undefined)\n Reflect.set(this, 'isSessionReused', () => false)\n Reflect.set(this, 'getCipher', () => ({\n name: 'AES256-SHA',\n standardName: 'TLS_RSA_WITH_AES_256_CBC_SHA',\n version: 'TLSv1.3',\n }))\n }\n }\n\n public emit(event: string | symbol, ...args: any[]): boolean {\n const emitEvent = super.emit.bind(this, event as any, ...args)\n\n if (this.responseListenersPromise) {\n this.responseListenersPromise.finally(emitEvent)\n return this.listenerCount(event) > 0\n }\n\n return emitEvent()\n }\n\n public destroy(error?: Error | undefined): this {\n // Destroy the response parser when the socket gets destroyed.\n // Normally, we should listen to the \"close\" event but it\n // can be suppressed by using the \"emitClose: false\" option.\n freeParser(this.responseParser, this)\n\n if (error) {\n this.emit('error', error)\n }\n\n return super.destroy(error)\n }\n\n /**\n * Establish this Socket connection as-is and pipe\n * its data/events through this Socket.\n */\n public passthrough(): void {\n this.socketState = 'passthrough'\n\n if (this.destroyed) {\n return\n }\n\n const socket = this.createConnection()\n this.originalSocket = socket\n\n /**\n * @note Inherit the original socket's connection handle.\n * Without this, each push to the mock socket results in a\n * new \"connection\" listener being added (i.e. buffering pushes).\n * @see https://github.com/nodejs/node/blob/b18153598b25485ce4f54d0c5cb830a9457691ee/lib/net.js#L734\n */\n if ('_handle' in socket) {\n Object.defineProperty(this, '_handle', {\n value: socket._handle,\n enumerable: true,\n writable: true,\n })\n }\n\n // The client-facing socket can be destroyed in two ways:\n // 1. The developer destroys the socket.\n // 2. The passthrough socket \"close\" is forwarded to the socket.\n this.once('close', () => {\n socket.removeAllListeners()\n\n // If the closure didn't originate from the passthrough socket, destroy it.\n if (!socket.destroyed) {\n socket.destroy()\n }\n\n this.originalSocket = undefined\n })\n\n this.address = socket.address.bind(socket)\n\n // Flush the buffered \"socket.write()\" calls onto\n // the original socket instance (i.e. write request body).\n // Exhaust the \"requestBuffer\" in case this Socket\n // gets reused for different requests.\n let writeArgs: NormalizedSocketWriteArgs | undefined\n let headersWritten = false\n\n while ((writeArgs = this.writeBuffer.shift())) {\n if (writeArgs !== undefined) {\n if (!headersWritten) {\n const [chunk, encoding, callback] = writeArgs\n const chunkString = chunk.toString()\n const chunkBeforeRequestHeaders = chunkString.slice(\n 0,\n chunkString.indexOf('\\r\\n') + 2\n )\n const chunkAfterRequestHeaders = chunkString.slice(\n chunk.indexOf('\\r\\n\\r\\n')\n )\n const rawRequestHeaders = getRawFetchHeaders(this.request!.headers)\n const requestHeadersString = rawRequestHeaders\n // Skip the internal request ID deduplication header.\n .filter(([name]) => {\n return name.toLowerCase() !== INTERNAL_REQUEST_ID_HEADER_NAME\n })\n .map(([name, value]) => `${name}: ${value}`)\n .join('\\r\\n')\n\n // Modify the HTTP request message headers\n // to reflect any changes to the request headers\n // from the \"request\" event listener.\n const headersChunk = `${chunkBeforeRequestHeaders}${requestHeadersString}${chunkAfterRequestHeaders}`\n socket.write(headersChunk, encoding, callback)\n headersWritten = true\n continue\n }\n\n socket.write(...writeArgs)\n }\n }\n\n // Forward TLS Socket properties onto this Socket instance\n // in the case of a TLS/SSL connection.\n if (Reflect.get(socket, 'encrypted')) {\n const tlsProperties = [\n 'encrypted',\n 'authorized',\n 'getProtocol',\n 'getSession',\n 'isSessionReused',\n 'getCipher',\n ]\n\n tlsProperties.forEach((propertyName) => {\n Object.defineProperty(this, propertyName, {\n enumerable: true,\n get: () => {\n const value = Reflect.get(socket, propertyName)\n return typeof value === 'function' ? value.bind(socket) : value\n },\n })\n })\n }\n\n socket\n .on('lookup', (...args) => this.emit('lookup', ...args))\n .on('connect', () => {\n this.connecting = socket.connecting\n this.emit('connect')\n })\n .on('secureConnect', () => this.emit('secureConnect'))\n .on('secure', () => this.emit('secure'))\n .on('session', (session) => this.emit('session', session))\n .on('ready', () => this.emit('ready'))\n .on('drain', () => this.emit('drain'))\n .on('data', (chunk) => {\n // Push the original response to this socket\n // so it triggers the HTTP response parser. This unifies\n // the handling pipeline for original and mocked response.\n this.push(chunk)\n })\n .on('error', (error) => {\n Reflect.set(this, '_hadError', Reflect.get(socket, '_hadError'))\n this.emit('error', error)\n })\n .on('resume', () => this.emit('resume'))\n .on('timeout', () => this.emit('timeout'))\n .on('prefinish', () => this.emit('prefinish'))\n .on('finish', () => this.emit('finish'))\n .on('close', (hadError) => this.emit('close', hadError))\n .on('end', () => this.emit('end'))\n }\n\n /**\n * Convert the given Fetch API `Response` instance to an\n * HTTP message and push it to the socket.\n */\n public async respondWith(response: Response): Promise<void> {\n // Ignore the mocked response if the socket has been destroyed\n // (e.g. aborted or timed out),\n if (this.destroyed) {\n return\n }\n\n // Prevent recursive calls.\n invariant(\n this.socketState !== 'mock',\n '[MockHttpSocket] Failed to respond to the \"%s %s\" request with \"%s %s\": the request has already been handled',\n this.request?.method,\n this.request?.url,\n response.status,\n response.statusText\n )\n\n // Handle \"type: error\" responses.\n if (isPropertyAccessible(response, 'type') && response.type === 'error') {\n this.errorWith(new TypeError('Network error'))\n return\n }\n\n // First, emit all the connection events\n // to emulate a successful connection.\n this.mockConnect()\n this.socketState = 'mock'\n\n // Flush the write buffer to trigger write callbacks\n // if it hasn't been flushed already (e.g. someone started reading request stream).\n this.flushWriteBuffer()\n\n // Create a `ServerResponse` instance to delegate HTTP message parsing,\n // Transfer-Encoding, and other things to Node.js internals.\n const serverResponse = new ServerResponse(new IncomingMessage(this))\n\n /**\n * Assign a mock socket instance to the server response to\n * spy on the response chunk writes. Push the transformed response chunks\n * to this `MockHttpSocket` instance to trigger the \"data\" event.\n * @note Providing the same `MockSocket` instance when creating `ServerResponse`\n * does not have the same effect.\n * @see https://github.com/nodejs/node/blob/10099bb3f7fd97bb9dd9667188426866b3098e07/test/parallel/test-http-server-response-standalone.js#L32\n */\n serverResponse.assignSocket(\n new MockSocket({\n write: (chunk, encoding, callback) => {\n this.push(chunk, encoding)\n callback?.()\n },\n read() {},\n })\n )\n\n /**\n * @note Remove the `Connection` and `Date` response headers\n * injected by `ServerResponse` by default. Those are required\n * from the server but the interceptor is NOT technically a server.\n * It's confusing to add response headers that the developer didn't\n * specify themselves. They can always add these if they wish.\n * @see https://www.rfc-editor.org/rfc/rfc9110#field.date\n * @see https://www.rfc-editor.org/rfc/rfc9110#field.connection\n */\n serverResponse.removeHeader('connection')\n serverResponse.removeHeader('date')\n\n const rawResponseHeaders = getRawFetchHeaders(response.headers)\n\n /**\n * @note Call `.writeHead` in order to set the raw response headers\n * in the same case as they were provided by the developer. Using\n * `.setHeader()`/`.appendHeader()` normalizes header names.\n */\n serverResponse.writeHead(\n response.status,\n response.statusText || STATUS_CODES[response.status],\n rawResponseHeaders\n )\n\n // If the developer destroy the socket, gracefully destroy the response.\n this.once('error', () => {\n serverResponse.destroy()\n })\n\n if (response.body) {\n try {\n const reader = response.body.getReader()\n\n while (true) {\n const { done, value } = await reader.read()\n\n if (done) {\n serverResponse.end()\n break\n }\n\n serverResponse.write(value)\n }\n } catch (error) {\n if (error instanceof Error) {\n serverResponse.destroy()\n /**\n * @note Destroy the request socket gracefully.\n * Response stream errors do NOT produce request errors.\n */\n this.destroy()\n return\n }\n\n serverResponse.destroy()\n throw error\n }\n } else {\n serverResponse.end()\n }\n\n // Close the socket if the connection wasn't marked as keep-alive.\n if (!this.shouldKeepAlive) {\n this.emit('readable')\n\n /**\n * @todo @fixme This is likely a hack.\n * Since we push null to the socket, it never propagates to the\n * parser, and the parser never calls \"onResponseEnd\" to close\n * the response stream. We are closing the stream here manually\n * but that shouldn't be the case.\n */\n this.responseStream?.push(null)\n this.push(null)\n }\n }\n\n /**\n * Close this socket connection with the given error.\n */\n public errorWith(error?: Error): void {\n this.destroy(error)\n }\n\n private mockConnect(): void {\n // Calling this method immediately puts the socket\n // into the connected state.\n this.connecting = false\n\n const isIPv6 =\n net.isIPv6(this.connectionOptions.hostname) ||\n this.connectionOptions.family === 6\n const addressInfo = {\n address: isIPv6 ? '::1' : '127.0.0.1',\n family: isIPv6 ? 'IPv6' : 'IPv4',\n port: this.connectionOptions.port,\n }\n // Return fake address information for the socket.\n this.address = () => addressInfo\n this.emit(\n 'lookup',\n null,\n addressInfo.address,\n addressInfo.family === 'IPv6' ? 6 : 4,\n this.connectionOptions.host\n )\n this.emit('connect')\n this.emit('ready')\n\n if (this.baseUrl.protocol === 'https:') {\n this.emit('secure')\n this.emit('secureConnect')\n\n // A single TLS connection is represented by two \"session\" events.\n this.emit(\n 'session',\n this.connectionOptions.session ||\n Buffer.from('mock-session-renegotiate')\n )\n this.emit('session', Buffer.from('mock-session-resume'))\n }\n }\n\n private flushWriteBuffer(): void {\n for (const writeCall of this.writeBuffer) {\n if (typeof writeCall[2] === 'function') {\n writeCall[2]()\n /**\n * @note Remove the callback from the write call\n * so it doesn't get called twice on passthrough\n * if `request.end()` was called within `request.write()`.\n * @see https://github.com/mswjs/interceptors/issues/684\n */\n writeCall[2] = undefined\n }\n }\n }\n\n /**\n * This callback might be called when the request is \"slow\":\n * - Request headers were fragmented across multiple TCP packages;\n * - Request headers were too large to be processed in a single run\n * (e.g. more than 30 request headers).\n * @note This is called before request start.\n */\n private onRequestHeaders: HeadersCallback = (rawHeaders) => {\n this.requestRawHeadersBuffer.push(...rawHeaders)\n }\n\n private onRequestStart: RequestHeadersCompleteCallback = (\n versionMajor,\n versionMinor,\n rawHeaders,\n _,\n path,\n __,\n ___,\n ____,\n shouldKeepAlive\n ) => {\n this.shouldKeepAlive = shouldKeepAlive\n\n const url = new URL(path || '', this.baseUrl)\n const method = this.connectionOptions.method?.toUpperCase() || 'GET'\n const headers = FetchResponse.parseRawHeaders([\n ...this.requestRawHeadersBuffer,\n ...(rawHeaders || []),\n ])\n this.requestRawHeadersBuffer.length = 0\n\n const canHaveBody = method !== 'GET' && method !== 'HEAD'\n\n // Translate the basic authorization in the URL to the request header.\n // Constructing a Request instance with a URL containing auth is no-op.\n if (url.username || url.password) {\n if (!headers.has('authorization')) {\n headers.set('authorization', `Basic ${url.username}:${url.password}`)\n }\n url.username = ''\n url.password = ''\n }\n\n // Create a new stream for each request.\n // If this Socket is reused for multiple requests,\n // this ensures that each request gets its own stream.\n // One Socket instance can only handle one request at a time.\n this.requestStream = new Readable({\n /**\n * @note Provide the `read()` method so a `Readable` could be\n * used as the actual request body (the stream calls \"read()\").\n * We control the queue in the onRequestBody/End functions.\n */\n read: () => {\n // If the user attempts to read the request body,\n // flush the write buffer to trigger the callbacks.\n // This way, if the request stream ends in the write callback,\n // it will indeed end correctly.\n this.flushWriteBuffer()\n },\n })\n\n const requestId = createRequestId()\n this.request = new Request(url, {\n method,\n headers,\n credentials: 'same-origin',\n // @ts-expect-error Undocumented Fetch property.\n duplex: canHaveBody ? 'half' : undefined,\n body: canHaveBody ? (Readable.toWeb(this.requestStream!) as any) : null,\n })\n\n Reflect.set(this.request, kRequestId, requestId)\n\n // Set the raw `http.ClientRequest` instance on the request instance.\n // This is useful for cases like getting the raw headers of the request.\n setRawRequest(this.request, Reflect.get(this, '_httpMessage'))\n\n // Create a copy of the request body stream and store it on the request.\n // This is only needed for the consumers who wish to read the request body stream\n // of requests that cannot have a body per Fetch API specification (i.e. GET, HEAD).\n setRawRequestBodyStream(this.request, this.requestStream)\n\n // Skip handling the request that's already being handled\n // by another (parent) interceptor. For example, XMLHttpRequest\n // is often implemented via ClientRequest in Node.js (e.g. JSDOM).\n // In that case, XHR interceptor will bubble down to the ClientRequest\n // interceptor. No need to try to handle that request again.\n /**\n * @fixme Stop relying on the \"X-Request-Id\" request header\n * to figure out if one interceptor has been invoked within another.\n * @see https://github.com/mswjs/interceptors/issues/378\n */\n if (this.request.headers.has(INTERNAL_REQUEST_ID_HEADER_NAME)) {\n this.passthrough()\n return\n }\n\n this.onRequest({\n requestId,\n request: this.request,\n socket: this,\n })\n }\n\n private onRequestBody(chunk: Buffer): void {\n invariant(\n this.requestStream,\n 'Failed to write to a request stream: stream does not exist'\n )\n\n this.requestStream.push(chunk)\n }\n\n private onRequestEnd(): void {\n // Request end can be called for requests without body.\n if (this.requestStream) {\n this.requestStream.push(null)\n }\n }\n\n /**\n * This callback might be called when the response is \"slow\":\n * - Response headers were fragmented across multiple TCP packages;\n * - Response headers were too large to be processed in a single run\n * (e.g. more than 30 response headers).\n * @note This is called before response start.\n */\n private onResponseHeaders: HeadersCallback = (rawHeaders) => {\n this.responseRawHeadersBuffer.push(...rawHeaders)\n }\n\n private onResponseStart: ResponseHeadersCompleteCallback = (\n versionMajor,\n versionMinor,\n rawHeaders,\n method,\n url,\n status,\n statusText\n ) => {\n const headers = FetchResponse.parseRawHeaders([\n ...this.responseRawHeadersBuffer,\n ...(rawHeaders || []),\n ])\n this.responseRawHeadersBuffer.length = 0\n\n const response = new FetchResponse(\n /**\n * @note The Fetch API response instance exposed to the consumer\n * is created over the response stream of the HTTP parser. It is NOT\n * related to the Socket instance. This way, you can read response body\n * in response listener while the Socket instance delays the emission\n * of \"end\" and other events until those response listeners are finished.\n */\n FetchResponse.isResponseWithBody(status)\n ? (Readable.toWeb(\n (this.responseStream = new Readable({ read() {} }))\n ) as any)\n : null,\n {\n url,\n status,\n statusText,\n headers,\n }\n )\n\n invariant(\n this.request,\n 'Failed to handle a response: request does not exist'\n )\n\n FetchResponse.setUrl(this.request.url, response)\n\n /**\n * @fixme Stop relying on the \"X-Request-Id\" request header\n * to figure out if one interceptor has been invoked within another.\n * @see https://github.com/mswjs/interceptors/issues/378\n */\n if (this.request.headers.has(INTERNAL_REQUEST_ID_HEADER_NAME)) {\n return\n }\n\n this.responseListenersPromise = this.onResponse({\n response,\n isMockedResponse: this.socketState === 'mock',\n requestId: Reflect.get(this.request, kRequestId),\n request: this.request,\n socket: this,\n })\n }\n\n private onResponseBody(chunk: Buffer) {\n invariant(\n this.responseStream,\n 'Failed to write to a response stream: stream does not exist'\n )\n\n this.responseStream.push(chunk)\n }\n\n private onResponseEnd(): void {\n // Response end can be called for responses without body.\n if (this.responseStream) {\n this.responseStream.push(null)\n }\n }\n}\n","/**\n * Here's how requests are handled in Node.js:\n *\n * 1. http.ClientRequest instance calls `agent.addRequest(request, options, cb)`.\n * 2. Agent creates a new socket: `agent.createSocket(options, cb)`.\n * 3. Agent creates a new connection: `agent.createConnection(options, cb)`.\n */\nimport net from 'node:net'\nimport http from 'node:http'\nimport https from 'node:https'\nimport {\n MockHttpSocket,\n type MockHttpSocketRequestCallback,\n type MockHttpSocketResponseCallback,\n} from './MockHttpSocket'\n\ndeclare module 'node:http' {\n interface Agent {\n options?: http.AgentOptions\n createConnection(options: any, callback: any): net.Socket\n }\n}\n\ninterface MockAgentOptions {\n customAgent?: http.RequestOptions['agent']\n onRequest: MockHttpSocketRequestCallback\n onResponse: MockHttpSocketResponseCallback\n}\n\nexport class MockAgent extends http.Agent {\n private customAgent?: http.RequestOptions['agent']\n private onRequest: MockHttpSocketRequestCallback\n private onResponse: MockHttpSocketResponseCallback\n\n constructor(options: MockAgentOptions) {\n super()\n this.customAgent = options.customAgent\n this.onRequest = options.onRequest\n this.onResponse = options.onResponse\n }\n\n public createConnection(options: any, callback: any): net.Socket {\n const createConnection =\n this.customAgent instanceof http.Agent\n ? this.customAgent.createConnection\n : super.createConnection\n\n const createConnectionOptions =\n this.customAgent instanceof http.Agent\n ? {\n ...options,\n ...this.customAgent.options,\n }\n : options\n\n const socket = new MockHttpSocket({\n connectionOptions: options,\n createConnection: createConnection.bind(\n this.customAgent || this,\n createConnectionOptions,\n callback\n ),\n onRequest: this.onRequest.bind(this),\n onResponse: this.onResponse.bind(this),\n })\n\n return socket\n }\n}\n\nexport class MockHttpsAgent extends https.Agent {\n private customAgent?: https.RequestOptions['agent']\n private onRequest: MockHttpSocketRequestCallback\n private onResponse: MockHttpSocketResponseCallback\n\n constructor(options: MockAgentOptions) {\n super()\n this.customAgent = options.customAgent\n this.onRequest = options.onRequest\n this.onResponse = options.onResponse\n }\n\n public createConnection(options: any, callback: any): net.Socket {\n const createConnection =\n this.customAgent instanceof http.Agent\n ? this.customAgent.createConnection\n : super.createConnection\n\n const createConnectionOptions =\n this.customAgent instanceof http.Agent\n ? {\n ...options,\n ...this.customAgent.options,\n }\n : options\n\n const socket = new MockHttpSocket({\n connectionOptions: options,\n createConnection: createConnection.bind(\n this.customAgent || this,\n createConnectionOptions,\n callback\n ),\n onRequest: this.onRequest.bind(this),\n onResponse: this.onResponse.bind(this),\n })\n\n return socket\n }\n}\n","import { Agent } from 'http'\nimport { RequestOptions, Agent as HttpsAgent } from 'https'\nimport { Logger } from '@open-draft/logger'\n\nconst logger = new Logger('utils getUrlByRequestOptions')\n\n// Request instance constructed by the \"request\" library\n// has a \"self\" property that has a \"uri\" field. This is\n// reproducible by performing a \"XMLHttpRequest\" request in JSDOM.\nexport interface RequestSelf {\n uri?: URL\n}\n\nexport type ResolvedRequestOptions = RequestOptions & RequestSelf\n\nexport const DEFAULT_PATH = '/'\nconst DEFAULT_PROTOCOL = 'http:'\nconst DEFAULT_HOSTNAME = 'localhost'\nconst SSL_PORT = 443\n\nfunction getAgent(\n options: ResolvedRequestOptions\n): Agent | HttpsAgent | undefined {\n return options.agent instanceof Agent ? options.agent : undefined\n}\n\nfunction getProtocolByRequestOptions(options: ResolvedRequestOptions): string {\n if (options.protocol) {\n return options.protocol\n }\n\n const agent = getAgent(options)\n const agentProtocol = (agent as RequestOptions)?.protocol\n\n if (agentProtocol) {\n return agentProtocol\n }\n\n const port = getPortByRequestOptions(options)\n const isSecureRequest = options.cert || port === SSL_PORT\n\n return isSecureRequest ? 'https:' : options.uri?.protocol || DEFAULT_PROTOCOL\n}\n\nfunction getPortByRequestOptions(\n options: ResolvedRequestOptions\n): number | undefined {\n // Use the explicitly provided port.\n if (options.port) {\n return Number(options.port)\n }\n\n // Otherwise, try to resolve port from the agent.\n const agent = getAgent(options)\n\n if ((agent as HttpsAgent)?.options.port) {\n return Number((agent as HttpsAgent).options.port)\n }\n\n if ((agent as RequestOptions)?.defaultPort) {\n return Number((agent as RequestOptions).defaultPort)\n }\n\n // Lastly, return undefined indicating that the port\n // must inferred from the protocol. Do not infer it here.\n return undefined\n}\n\ninterface RequestAuth {\n username: string\n password: string\n}\n\nfunction getAuthByRequestOptions(\n options: ResolvedRequestOptions\n): RequestAuth | undefined {\n if (options.auth) {\n const [username, password] = options.auth.split(':')\n return { username, password }\n }\n}\n\n/**\n * Returns true if host looks like an IPv6 address without surrounding brackets\n * It assumes any host containing `:` is definitely not IPv4 and probably IPv6,\n * but note that this could include invalid IPv6 addresses as well.\n */\nfunction isRawIPv6Address(host: string): boolean {\n return host.includes(':') && !host.startsWith('[') && !host.endsWith(']')\n}\n\nfunction getHostname(options: ResolvedRequestOptions): string | undefined {\n let host = options.hostname || options.host\n\n if (host) {\n if (isRawIPv6Address(host)) {\n host = `[${host}]`\n }\n\n // Check the presence of the port, and if it's present,\n // remove it from the host, returning a hostname.\n return new URL(`http://${host}`).hostname\n }\n\n return DEFAULT_HOSTNAME\n}\n\n/**\n * Creates a `URL` instance from a given `RequestOptions` object.\n */\nexport function getUrlByRequestOptions(options: ResolvedRequestOptions): URL {\n logger.info('request options', options)\n\n if (options.uri) {\n logger.info(\n 'constructing url from explicitly provided \"options.uri\": %s',\n options.uri\n )\n return new URL(options.uri.href)\n }\n\n logger.info('figuring out url from request options...')\n\n const protocol = getProtocolByRequestOptions(options)\n logger.info('protocol', protocol)\n\n const port = getPortByRequestOptions(options)\n logger.info('port', port)\n\n const hostname = getHostname(options)\n logger.info('hostname', hostname)\n\n const path = options.path || DEFAULT_PATH\n logger.info('path', path)\n\n const credentials = getAuthByRequestOptions(options)\n logger.info('credentials', credentials)\n\n const authString = credentials\n ? `${credentials.username}:${credentials.password}@`\n : ''\n logger.info('auth string:', authString)\n\n const portString = typeof port !== 'undefined' ? `:${port}` : ''\n const url = new URL(`${protocol}//${hostname}${portString}${path}`)\n url.username = credentials?.username || ''\n url.password = credentials?.password || ''\n\n logger.info('created url:', url)\n\n return url\n}\n","import { Logger } from '@open-draft/logger'\n\nconst logger = new Logger('cloneObject')\n\nfunction isPlainObject(obj?: Record<string, any>): boolean {\n logger.info('is plain object?', obj)\n\n if (obj == null || !obj.constructor?.name) {\n logger.info('given object is undefined, not a plain object...')\n return false\n }\n\n logger.info('checking the object constructor:', obj.constructor.name)\n return obj.constructor.name === 'Object'\n}\n\nexport function cloneObject<ObjectType extends Record<string, any>>(\n obj: ObjectType\n): ObjectType {\n logger.info('cloning object:', obj)\n\n const enumerableProperties = Object.entries(obj).reduce<Record<string, any>>(\n (acc, [key, value]) => {\n logger.info('analyzing key-value pair:', key, value)\n\n // Recursively clone only plain objects, omitting class instances.\n acc[key] = isPlainObject(value) ? cloneObject(value) : value\n return acc\n },\n {}\n )\n\n return isPlainObject(obj)\n ? enumerableProperties\n : Object.assign(Object.getPrototypeOf(obj), enumerableProperties)\n}\n","import { urlToHttpOptions } from 'node:url'\nimport {\n Agent as HttpAgent,\n globalAgent as httpGlobalAgent,\n IncomingMessage,\n} from 'node:http'\nimport {\n RequestOptions,\n Agent as HttpsAgent,\n globalAgent as httpsGlobalAgent,\n} from 'node:https'\nimport {\n /**\n * @note Use the Node.js URL instead of the global URL\n * because environments like JSDOM may override the global,\n * breaking the compatibility with Node.js.\n * @see https://github.com/node-fetch/node-fetch/issues/1376#issuecomment-966435555\n */\n URL,\n Url as LegacyURL,\n parse as parseUrl,\n} from 'node:url'\nimport { Logger } from '@open-draft/logger'\nimport {\n ResolvedRequestOptions,\n getUrlByRequestOptions,\n} from '../../../utils/getUrlByRequestOptions'\nimport { cloneObject } from '../../../utils/cloneObject'\nimport { isObject } from '../../../utils/isObject'\n\nconst logger = new Logger('http normalizeClientRequestArgs')\n\nexport type HttpRequestCallback = (response: IncomingMessage) => void\n\nexport type ClientRequestArgs =\n // Request without any arguments is also possible.\n | []\n | [string | URL | LegacyURL, HttpRequestCallback?]\n | [string | URL | LegacyURL, RequestOptions, HttpRequestCallback?]\n | [RequestOptions, HttpRequestCallback?]\n\nfunction resolveRequestOptions(\n args: ClientRequestArgs,\n url: URL\n): RequestOptions {\n // Calling `fetch` provides only URL to `ClientRequest`\n // without any `RequestOptions` or callback.\n if (typeof args[1] === 'undefined' || typeof args[1] === 'function') {\n logger.info('request options not provided, deriving from the url', url)\n return urlToHttpOptions(url)\n }\n\n if (args[1]) {\n logger.info('has custom RequestOptions!', args[1])\n const requestOptionsFromUrl = urlToHttpOptions(url)\n\n logger.info('derived RequestOptions from the URL:', requestOptionsFromUrl)\n\n /**\n * Clone the request options to lock their state\n * at the moment they are provided to `ClientRequest`.\n * @see https://github.com/mswjs/interceptors/issues/86\n */\n logger.info('cloning RequestOptions...')\n const clonedRequestOptions = cloneObject(args[1])\n logger.info('successfully cloned RequestOptions!', clonedRequestOptions)\n\n return {\n ...requestOptionsFromUrl,\n ...clonedRequestOptions,\n }\n }\n\n logger.info('using an empty object as request options')\n return {} as RequestOptions\n}\n\n/**\n * Overrides the given `URL` instance with the explicit properties provided\n * on the `RequestOptions` object. The options object takes precedence,\n * and will replace URL properties like \"host\", \"path\", and \"port\", if specified.\n */\nfunction overrideUrlByRequestOptions(url: URL, options: RequestOptions): URL {\n url.host = options.host || url.host\n url.hostname = options.hostname || url.hostname\n url.port = options.port ? options.port.toString() : url.port\n\n if (options.path) {\n const parsedOptionsPath = parseUrl(options.path, false)\n url.pathname = parsedOptionsPath.pathname || ''\n url.search = parsedOptionsPath.search || ''\n }\n\n return url\n}\n\nfunction resolveCallback(\n args: ClientRequestArgs\n): HttpRequestCallback | undefined {\n return typeof args[1] === 'function' ? args[1] : args[2]\n}\n\nexport type NormalizedClientRequestArgs = [\n url: URL,\n options: ResolvedRequestOptions,\n callback?: HttpRequestCallback\n]\n\n/**\n * Normalizes parameters given to a `http.request` call\n * so it always has a `URL` and `RequestOptions`.\n */\nexport function normalizeClientRequestArgs(\n defaultProtocol: string,\n args: ClientRequestArgs\n): NormalizedClientRequestArgs {\n let url: URL\n let options: ResolvedRequestOptions\n let callback: HttpRequestCallback | undefined\n\n logger.info('arguments', args)\n logger.info('using default protocol:', defaultProtocol)\n\n // Support \"http.request()\" calls without any arguments.\n // That call results in a \"GET http://localhost\" request.\n if (args.length === 0) {\n const url = new URL('http://localhost')\n const options = resolveRequestOptions(args, url)\n return [url, options]\n }\n\n // Convert a url string into a URL instance\n // and derive request options from it.\n if (typeof args[0] === 'string') {\n logger.info('first argument is a location string:', args[0])\n\n url = new URL(args[0])\n logger.info('created a url:', url)\n\n const requestOptionsFromUrl = urlToHttpOptions(url)\n logger.info('request options from url:', requestOptionsFromUrl)\n\n options = resolveRequestOptions(args, url)\n logger.info('resolved request options:', options)\n\n callback = resolveCallback(args)\n }\n // Handle a given URL instance as-is\n // and derive request options from it.\n else if (args[0] instanceof URL) {\n url = args[0]\n logger.info('first argument is a URL:', url)\n\n // Check if the second provided argument is RequestOptions.\n // If it is, check if \"options.path\" was set and rewrite it\n // on the input URL.\n // Do this before resolving options from the URL below\n // to prevent query string from being duplicated in the path.\n if (typeof args[1] !== 'undefined' && isObject<RequestOptions>(args[1])) {\n url = overrideUrlByRequestOptions(url, args[1])\n }\n\n options = resolveRequestOptions(args, url)\n logger.info('derived request options:', options)\n\n callback = resolveCallback(args)\n }\n // Handle a legacy URL instance and re-normalize from either a RequestOptions object\n // or a WHATWG URL.\n else if ('hash' in args[0] && !('method' in args[0])) {\n const [legacyUrl] = args\n logger.info('first argument is a legacy URL:', legacyUrl)\n\n if (legacyUrl.hostname === null) {\n /**\n * We are dealing with a relative url, so use the path as an \"option\" and\n * merge in any existing options, giving priority to existing options -- i.e. a path in any\n * existing options will take precedence over the one contained in the url. This is consistent\n * with the behaviour in ClientRequest.\n * @see https://github.com/nodejs/node/blob/d84f1312915fe45fe0febe888db692c74894c382/lib/_http_client.js#L122\n */\n logger.info('given legacy URL is relative (no hostname)')\n\n return isObject(args[1])\n ? normalizeClientRequestArgs(defaultProtocol, [\n { path: legacyUrl.path, ...args[1] },\n args[2],\n ])\n : normalizeClientRequestArgs(defaultProtocol, [\n { path: legacyUrl.path },\n args[1] as HttpRequestCallback,\n ])\n }\n\n logger.info('given legacy url is absolute')\n\n // We are dealing with an absolute URL, so convert to WHATWG and try again.\n const resolvedUrl = new URL(legacyUrl.href)\n\n return args[1] === undefined\n ? normalizeClientRequestArgs(defaultProtocol, [resolvedUrl])\n : typeof args[1] === 'function'\n ? normalizeClientRequestArgs(defaultProtocol, [resolvedUrl, args[1]])\n : normalizeClientRequestArgs(defaultProtocol, [\n resolvedUrl,\n args[1],\n args[2],\n ])\n }\n // Handle a given \"RequestOptions\" object as-is\n // and derive the URL instance from it.\n else if (isObject(args[0])) {\n options = { ...(args[0] as any) }\n logger.info('first argument is RequestOptions:', options)\n\n // When handling a \"RequestOptions\" object without an explicit \"protocol\",\n // infer the protocol from the request issuing module (http/https).\n options.protocol = options.protocol || defaultProtocol\n logger.info('normalized request options:', options)\n\n url = getUrlByRequestOptions(options)\n logger.info('created a URL from RequestOptions:', url.href)\n\n callback = resolveCallback(args)\n } else {\n throw new Error(\n `Failed to construct ClientRequest with these parameters: ${args}`\n )\n }\n\n options.protocol = options.protocol || url.protocol\n options.method = options.method || 'GET'\n\n /**\n * Ensure that the default Agent is always set.\n * This prevents the protocol mismatch for requests with { agent: false },\n * where the global Agent is inferred.\n * @see https://github.com/mswjs/msw/issues/1150\n * @see https://github.com/nodejs/node/blob/418ff70b810f0e7112d48baaa72932a56cfa213b/lib/_http_client.js#L130\n * @see https://github.com/nodejs/node/blob/418ff70b810f0e7112d48baaa72932a56cfa213b/lib/_http_client.js#L157-L159\n */\n if (!options._defaultAgent) {\n logger.info(\n 'has no default agent, setting the default agent for \"%s\"',\n options.protocol\n )\n\n options._defaultAgent =\n options.protocol === 'https:' ? httpsGlobalAgent : httpGlobalAgent\n }\n\n logger.info('successfully resolved url:', url.href)\n logger.info('successfully resolved options:', options)\n logger.info('successfully resolved callback:', callback)\n\n /**\n * @note If the user-provided URL is not a valid URL in Node.js,\n * (e.g. the one provided by the JSDOM polyfills), case it to\n * string. Otherwise, this throws on Node.js incompatibility\n * (`ERR_INVALID_ARG_TYPE` on the connection listener)\n * @see https://github.com/node-fetch/node-fetch/issues/1376#issuecomment-966435555\n */\n if (!(url instanceof URL)) {\n url = (url as any).toString()\n }\n\n return [url, options, callback]\n}\n","import http from 'node:http'\nimport https from 'node:https'\nimport { Interceptor } from '../../Interceptor'\nimport type { HttpRequestEventMap } from '../../glossary'\nimport {\n kRequestId,\n MockHttpSocketRequestCallback,\n MockHttpSocketResponseCallback,\n} from './MockHttpSocket'\nimport { MockAgent, MockHttpsAgent } from './agents'\nimport { RequestController } from '../../RequestController'\nimport { emitAsync } from '../../utils/emitAsync'\nimport { normalizeClientRequestArgs } from './utils/normalizeClientRequestArgs'\nimport { handleRequest } from '../../utils/handleRequest'\nimport {\n recordRawFetchHeaders,\n restoreHeadersPrototype,\n} from './utils/recordRawHeaders'\n\nexport class ClientRequestInterceptor extends Interceptor<HttpRequestEventMap> {\n static symbol = Symbol('client-request-interceptor')\n\n constructor() {\n super(ClientRequestInterceptor.symbol)\n }\n\n protected setup(): void {\n const {\n ClientRequest: OriginalClientRequest,\n get: originalGet,\n request: originalRequest,\n } = http\n const { get: originalHttpsGet, request: originalHttpsRequest } = https\n\n const onRequest = this.onRequest.bind(this)\n const onResponse = this.onResponse.bind(this)\n\n // Support requests performed via the `ClientRequest` constructor directly.\n http.ClientRequest = new Proxy(http.ClientRequest, {\n construct: (target, args: Parameters<typeof http.request>) => {\n const [url, options, callback] = normalizeClientRequestArgs(\n 'http:',\n args\n )\n\n // Create a mock agent instance appropriate for the request protocol.\n const Agent = options.protocol === 'https:' ? MockHttpsAgent : MockAgent\n const mockAgent = new Agent({\n customAgent: options.agent,\n onRequest,\n onResponse,\n })\n options.agent = mockAgent\n\n return Reflect.construct(target, [url, options, callback])\n },\n })\n\n http.request = new Proxy(http.request, {\n apply: (target, thisArg, args: Parameters<typeof http.request>) => {\n const [url, options, callback] = normalizeClientRequestArgs(\n 'http:',\n args\n )\n const mockAgent = new MockAgent({\n customAgent: options.agent,\n onRequest,\n onResponse,\n })\n options.agent = mockAgent\n\n return Reflect.apply(target, thisArg, [url, options, callback])\n },\n })\n\n http.get = new Proxy(http.get, {\n apply: (target, thisArg, args: Parameters<typeof http.get>) => {\n const [url, options, callback] = normalizeClientRequestArgs(\n 'http:',\n args\n )\n\n const mockAgent = new MockAgent({\n customAgent: options.agent,\n onRequest,\n onResponse,\n })\n options.agent = mockAgent\n\n return Reflect.apply(target, thisArg, [url, options, callback])\n },\n })\n\n //\n // HTTPS.\n //\n\n https.request = new Proxy(https.request, {\n apply: (target, thisArg, args: Parameters<typeof https.request>) => {\n const [url, options, callback] = normalizeClientRequestArgs(\n 'https:',\n args\n )\n\n const mockAgent = new MockHttpsAgent({\n customAgent: options.agent,\n onRequest,\n onResponse,\n })\n options.agent = mockAgent\n\n return Reflect.apply(target, thisArg, [url, options, callback])\n },\n })\n\n https.get = new Proxy(https.get, {\n apply: (target, thisArg, args: Parameters<typeof https.get>) => {\n const [url, options, callback] = normalizeClientRequestArgs(\n 'https:',\n args\n )\n\n const mockAgent = new MockHttpsAgent({\n customAgent: options.agent,\n onRequest,\n onResponse,\n })\n options.agent = mockAgent\n\n return Reflect.apply(target, thisArg, [url, options, callback])\n },\n })\n\n // Spy on `Header.prototype.set` and `Header.prototype.append` calls\n // and record the raw header names provided. This is to support\n // `IncomingMessage.prototype.rawHeaders`.\n recordRawFetchHeaders()\n\n this.subscriptions.push(() => {\n http.ClientRequest = OriginalClientRequest\n\n http.get = originalGet\n http.request = originalRequest\n\n https.get = originalHttpsGet\n https.request = originalHttpsRequest\n\n restoreHeadersPrototype()\n })\n }\n\n private onRequest: MockHttpSocketRequestCallback = async ({\n request,\n socket,\n }) => {\n const controller = new RequestController(request, {\n passthrough() {\n socket.passthrough()\n },\n async respondWith(response) {\n await socket.respondWith(response)\n },\n errorWith(reason) {\n if (reason instanceof Error) {\n socket.errorWith(reason)\n }\n },\n })\n\n await handleRequest({\n request,\n requestId: Reflect.get(request, kRequestId),\n controller,\n emitter: this.emitter,\n })\n }\n\n public onResponse: MockHttpSocketResponseCallback = async ({\n requestId,\n request,\n response,\n isMockedResponse,\n }) => {\n // Return the promise to when all the response event listeners\n // are finished.\n return emitAsync(this.emitter, 'response', {\n requestId,\n request,\n response,\n isMockedResponse,\n })\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAgBA,SAAgB,yBACd,MAC2B;CAC3B,MAAMA,aAAwC;EAAC,KAAK;EAAI;EAAW;EAAU;AAE7E,KAAI,OAAO,KAAK,OAAO,SACrB,YAAW,KAAK,KAAK;UACZ,OAAO,KAAK,OAAO,WAC5B,YAAW,KAAK,KAAK;AAGvB,KAAI,OAAO,KAAK,OAAO,WACrB,YAAW,KAAK,KAAK;AAGvB,QAAO;;;;;ACdT,IAAa,aAAb,cAAgCC,iBAAI,OAAO;CAGzC,YAAY,AAAmBC,SAA4B;AACzD,SAAO;EADsB;AAE7B,OAAK,aAAa;AAClB,OAAK,SAAS;AAEd,OAAK,UAAU,aAAa;AAC1B,YAAS,KAAK;;;CAIlB,AAAO,UAAU;AAGf,OAAK,aAAa;AAClB,SAAO;;CAGT,AAAO,MAAM,GAAG,MAA+B;EAC7C,MAAM,CAAC,OAAO,UAAU,YAAY,yBAClC,KACD;AACD,OAAK,QAAQ,MAAM,OAAO,UAAU,SAAS;AAC7C,SAAO;;CAGT,AAAO,IAAI,GAAG,MAAsB;EAClC,MAAM,CAAC,OAAO,UAAU,YAAY,yBAClC,KACD;AACD,OAAK,QAAQ,MAAM,OAAO,UAAU,SAAS;AAC7C,SAAO,MAAM,IAAI,MAAM,MAAM,KAAY;;CAG3C,AAAO,KAAK,OAAY,UAAoC;AAC1D,OAAK,QAAQ,KAAK,OAAO,SAAS;AAClC,SAAO,MAAM,KAAK,OAAO,SAAS;;;;;;ACvDtC,SAAgB,6BAA6B,SAAmB;AAC9D,KAAI,UAAU,QACZ,QAAO,IAAI,IAAI,QAAQ,KAAK;CAG9B,MAAM,WAAW,QAAQ,SAAS,MAAM,WAAW;CACnD,MAAM,OAAO,QAAQ;CAErB,MAAM,MAAM,IAAI,IAAI,GAAG,SAAS,IAAI,OAAO;AAE3C,KAAI,QAAQ,KACV,KAAI,OAAO,QAAQ,KAAK,UAAU;AAGpC,KAAI,QAAQ,KACV,KAAI,WAAW,QAAQ;AAGzB,KAAI,QAAQ,MAAM;EAChB,MAAM,CAAC,UAAU,YAAY,QAAQ,KAAK,MAAM,IAAI;AACpD,MAAI,WAAW;AACf,MAAI,WAAW;;AAGjB,QAAO;;;;;ACpBT,MAAM,cAAc,OAAO,cAAc;AACzC,MAAM,kBAAkB,OAAO,kBAAkB;AAEjD,SAAS,gBACP,SACA,MACA,UACA;AACA,wBAAuB,SAAS,EAAE,CAAC;CACnC,MAAM,aAAa,QAAQ,IAAI,SAAS,YAAY;AAEpD,KAAI,aAAa,OAEf;OAAK,IAAI,QAAQ,WAAW,SAAS,GAAG,SAAS,GAAG,QAClD,KAAI,WAAW,OAAO,GAAG,aAAa,KAAK,KAAK,GAAG,aAAa,CAC9D,YAAW,OAAO,OAAO,EAAE;;AAKjC,YAAW,KAAK,KAAK;;;;;;AAOvB,SAAS,uBACP,SACA,YACM;AACN,KAAI,QAAQ,IAAI,SAAS,YAAY,CACnC;AAGF,wBAAuB,SAAS,WAAW;;;;;;AAO7C,SAAS,uBAAuB,SAAkB,YAAwB;AACxE,QAAO,eAAe,SAAS,aAAa;EAC1C,OAAO;EACP,YAAY;EAIZ,cAAc;EACf,CAAC;;;;;;;;;;;;;;;;AAiBJ,SAAgB,wBAAwB;AAEtC,KAAI,QAAQ,IAAI,SAAS,gBAAgB,CACvC,QAAO,QAAQ,IAAI,SAAS,gBAAgB;CAG9C,MAAM,EACJ,SAAS,iBACT,SAAS,iBACT,UAAU,qBACR;CACJ,MAAM,EAAE,KAAK,QAAQ,QAAQ,wBAAwB,QAAQ;AAE7D,QAAO,eAAe,SAAS,iBAAiB;EAC9C,aAAa;AACX,WAAQ,UAAU,MAAM;AACxB,WAAQ,UAAU,SAAS;AAC3B,WAAQ,UAAU,SAAS;AAC3B,cAAW,UAAU;AAErB,cAAW,UAAU;AACrB,cAAW,WAAW;AAEtB,WAAQ,eAAe,SAAS,gBAAgB;;EAElD,YAAY;EAKZ,cAAc;EACf,CAAC;AAEF,QAAO,eAAe,YAAY,WAAW;EAC3C,YAAY;EACZ,UAAU;EACV,OAAO,IAAI,MAAM,SAAS,EACxB,UAAU,QAAQ,MAAM,WAAW;GACjC,MAAM,cAAc,KAAK,MAAM,EAAE;AAEjC,OACE,uBAAuB,WACvB,QAAQ,IAAI,aAAa,YAAY,EACrC;IACA,MAAMC,YAAU,QAAQ,UACtB,QACA,CAAC,QAAQ,IAAI,aAAa,YAAY,CAAC,EACvC,UACD;AACD,2BAAuBA,WAAS,CAM9B,GAAG,QAAQ,IAAI,aAAa,YAAY,CACzC,CAAC;AACF,WAAOA;;GAGT,MAAM,UAAU,QAAQ,UAAU,QAAQ,MAAM,UAAU;AAM1D,OAAI,CAAC,QAAQ,IAAI,SAAS,YAAY,CAIpC,wBAAuB,SAHA,MAAM,QAAQ,YAAY,GAC7C,cACA,OAAO,QAAQ,YAAY,CACgB;AAGjD,UAAO;KAEV,CAAC;EACH,CAAC;AAEF,SAAQ,UAAU,MAAM,IAAI,MAAM,QAAQ,UAAU,KAAK,EACvD,MAAM,QAAQ,SAAS,MAAmB;AACxC,kBAAgB,SAAS,MAAM,MAAM;AACrC,SAAO,QAAQ,MAAM,QAAQ,SAAS,KAAK;IAE9C,CAAC;AAEF,SAAQ,UAAU,SAAS,IAAI,MAAM,QAAQ,UAAU,QAAQ,EAC7D,MAAM,QAAQ,SAAS,MAAmB;AACxC,kBAAgB,SAAS,MAAM,SAAS;AACxC,SAAO,QAAQ,MAAM,QAAQ,SAAS,KAAK;IAE9C,CAAC;AAEF,SAAQ,UAAU,SAAS,IAAI,MAAM,QAAQ,UAAU,QAAQ,EAC7D,MAAM,QAAQ,SAAS,MAAgB;EACrC,MAAM,aAAa,QAAQ,IAAI,SAAS,YAAY;AAEpD,MAAI,YACF;QAAK,IAAI,QAAQ,WAAW,SAAS,GAAG,SAAS,GAAG,QAClD,KAAI,WAAW,OAAO,GAAG,aAAa,KAAK,KAAK,GAAG,aAAa,CAC9D,YAAW,OAAO,OAAO,EAAE;;AAKjC,SAAO,QAAQ,MAAM,QAAQ,SAAS,KAAK;IAE9C,CAAC;AAEF,QAAO,eAAe,YAAY,WAAW;EAC3C,YAAY;EACZ,UAAU;EACV,OAAO,IAAI,MAAM,SAAS,EACxB,UAAU,QAAQ,MAAM,WAAW;GACjC,MAAM,UAAU,QAAQ,UAAU,QAAQ,MAAM,UAAU;GAC1D,MAAMC,qBAAiC,EAAE;AAGzC,OAAI,OAAO,KAAK,OAAO,YAAY,KAAK,GAAG,WAAW,KACpD,oBAAmB,KAAK,GAAG,gBAAgB,KAAK,GAAG,QAAQ,CAAC;AAI9D,OAAI,OAAO,KAAK,OAAO,YAAY,KAAK,GAAG,WAAW,KACpD,oBAAmB,KAAK,GAAG,gBAAgB,KAAK,GAAG,QAAQ,CAAC;AAG9D,OAAI,mBAAmB,SAAS,EAC9B,wBAAuB,QAAQ,SAAS,mBAAmB;AAG7D,UAAO;KAEV,CAAC;EACH,CAAC;AAEF,QAAO,eAAe,YAAY,YAAY;EAC5C,YAAY;EACZ,UAAU;EACV,OAAO,IAAI,MAAM,UAAU,EACzB,UAAU,QAAQ,MAAM,WAAW;GACjC,MAAM,WAAW,QAAQ,UAAU,QAAQ,MAAM,UAAU;AAE3D,OAAI,OAAO,KAAK,OAAO,YAAY,KAAK,GAAG,WAAW,KACpD,wBACE,SAAS,SACT,gBAAgB,KAAK,GAAG,QAAQ,CACjC;AAGH,UAAO;KAEV,CAAC;EACH,CAAC;;AAGJ,SAAgB,0BAA0B;AACxC,KAAI,CAAC,QAAQ,IAAI,SAAS,gBAAgB,CACxC;AAGF,SAAQ,IAAI,SAAS,gBAAgB,EAAE;;AAGzC,SAAgB,mBAAmB,SAA8B;AAG/D,KAAI,CAAC,QAAQ,IAAI,SAAS,YAAY,CACpC,QAAO,MAAM,KAAK,QAAQ,SAAS,CAAC;CAGtC,MAAM,aAAa,QAAQ,IAAI,SAAS,YAAY;AACpD,QAAO,WAAW,SAAS,IAAI,aAAa,MAAM,KAAK,QAAQ,SAAS,CAAC;;;;;;;;;;;;AAa3E,SAAS,gBAAgB,SAAkC;AACzD,KAAI,mBAAmB,QACrB,QAAO,QAAQ,IAAI,SAAS,YAAY,IAAI,EAAE;AAGhD,QAAO,QAAQ,IAAI,IAAI,QAAQ,QAAQ,EAAE,YAAY;;;;;;;;AC9PvD,SAAgB,WAAW,QAAyB,QAAuB;AACzE,KAAI,OAAO,UACT,QAAO,WAAW;AAGpB,QAAO,WAAW,EAAE;AACpB,QAAO,OAAO;AACd,QAAO,SAAS;AAChB,QAAO,WAAW;AAClB,QAAO,WAAW;AAClB,QAAO,iBAAiB;AACxB,QAAO,YAAY;AACnB,QAAO,aAAa;AAEpB,QAAOC,wBAAW,cAAc;AAChC,QAAOA,wBAAW,sBAAsB;AACxC,QAAOA,wBAAW,mBAAmB;AACrC,QAAOA,wBAAW,sBAAsB;AACxC,QAAOA,wBAAW,WAAW;AAC7B,QAAOA,wBAAW,cAAc;AAChC,QAAOA,wBAAW,cAAc;AAEhC,QAAO,QAAQ;AACf,QAAO,MAAM;AAEb,KAAI;;;;;;AAMF,KAAI,OAAO,UAET,QAAO,SAAS;KAEhB,QAAO,KAAK,aAAa;AAEvB,SAAO,SAAS;GAChB;;;;;ACCR,MAAa,aAAa,OAAO,aAAa;AAE9C,IAAa,iBAAb,cAAoC,WAAW;CAsB7C,YAAY,SAAgC;AAC1C,QAAM;GACJ,QAAQ,OAAO,UAAU,aAAa;AAIpC,QAAI,KAAK,gBAAgB,cACvB,MAAK,YAAY,KAAK;KAAC;KAAO;KAAU;KAAS,CAAC;AAGpD,QAAI,OAAO;;;;;;AAMT,SAAI,KAAK,gBAAgB,cACvB,MAAK,gBAAgB,MAAM,OAAO,UAAU,SAAS;AAGvD,UAAK,cAAc,QACjB,OAAO,SAAS,MAAM,GAAG,QAAQ,OAAO,KAAK,OAAO,SAAS,CAC9D;;;GAGL,OAAO,UAAU;AACf,QAAI,UAAU;;;;;;AAMZ,SAAK,eAAe,QAClB,OAAO,SAAS,MAAM,GAAG,QAAQ,OAAO,KAAK,MAAM,CACpD;;GAGN,CAAC;iCAlD6C,EAAE;kCACD,EAAE;qBACI,EAAE;qBAMA;2BAycb,eAAe;AAC1D,QAAK,wBAAwB,KAAK,GAAG,WAAW;;yBAIhD,cACA,cACA,YACA,GACA,MACA,IACA,KACA,MACA,oBACG;AACH,QAAK,kBAAkB;GAEvB,MAAM,MAAM,IAAI,IAAI,QAAQ,IAAI,KAAK,QAAQ;GAC7C,MAAM,SAAS,KAAK,kBAAkB,QAAQ,aAAa,IAAI;GAC/D,MAAM,UAAUC,iCAAc,gBAAgB,CAC5C,GAAG,KAAK,yBACR,GAAI,cAAc,EAAE,CACrB,CAAC;AACF,QAAK,wBAAwB,SAAS;GAEtC,MAAM,cAAc,WAAW,SAAS,WAAW;AAInD,OAAI,IAAI,YAAY,IAAI,UAAU;AAChC,QAAI,CAAC,QAAQ,IAAI,gBAAgB,CAC/B,SAAQ,IAAI,iBAAiB,SAAS,IAAI,SAAS,GAAG,IAAI,WAAW;AAEvE,QAAI,WAAW;AACf,QAAI,WAAW;;AAOjB,QAAK,gBAAgB,IAAIC,qBAAS,EAMhC,YAAY;AAKV,SAAK,kBAAkB;MAE1B,CAAC;GAEF,MAAM,YAAYC,oCAAiB;AACnC,QAAK,UAAU,IAAI,QAAQ,KAAK;IAC9B;IACA;IACA,aAAa;IAEb,QAAQ,cAAc,SAAS;IAC/B,MAAM,cAAeD,qBAAS,MAAM,KAAK,cAAe,GAAW;IACpE,CAAC;AAEF,WAAQ,IAAI,KAAK,SAAS,YAAY,UAAU;AAIhD,uCAAc,KAAK,SAAS,QAAQ,IAAI,MAAM,eAAe,CAAC;AAK9D,wCAAwB,KAAK,SAAS,KAAK,cAAc;;;;;;AAYzD,OAAI,KAAK,QAAQ,QAAQ,IAAIE,mDAAgC,EAAE;AAC7D,SAAK,aAAa;AAClB;;AAGF,QAAK,UAAU;IACb;IACA,SAAS,KAAK;IACd,QAAQ;IACT,CAAC;;4BA0B0C,eAAe;AAC3D,QAAK,yBAAyB,KAAK,GAAG,WAAW;;0BAIjD,cACA,cACA,YACA,QACA,KACA,QACA,eACG;GACH,MAAM,UAAUH,iCAAc,gBAAgB,CAC5C,GAAG,KAAK,0BACR,GAAI,cAAc,EAAE,CACrB,CAAC;AACF,QAAK,yBAAyB,SAAS;GAEvC,MAAM,WAAW,IAAIA;;;;;;;;IAQnBA,iCAAc,mBAAmB,OAAO,GACnCC,qBAAS,MACP,KAAK,iBAAiB,IAAIA,qBAAS,EAAE,OAAO,IAAI,CAAC,CACnD,GACD;IACJ;KACE;KACA;KACA;KACA;KACD;IACF;AAED,6BACE,KAAK,SACL,sDACD;AAED,oCAAc,OAAO,KAAK,QAAQ,KAAK,SAAS;;;;;;AAOhD,OAAI,KAAK,QAAQ,QAAQ,IAAIE,mDAAgC,CAC3D;AAGF,QAAK,2BAA2B,KAAK,WAAW;IAC9C;IACA,kBAAkB,KAAK,gBAAgB;IACvC,WAAW,QAAQ,IAAI,KAAK,SAAS,WAAW;IAChD,SAAS,KAAK;IACd,QAAQ;IACT,CAAC;;AArlBF,OAAK,oBAAoB,QAAQ;AACjC,OAAK,mBAAmB,QAAQ;AAChC,OAAK,YAAY,QAAQ;AACzB,OAAK,aAAa,QAAQ;AAE1B,OAAK,UAAU,6BAA6B,KAAK,kBAAkB;AAGnE,OAAK,gBAAgB,IAAIC,yBAAY;AACrC,OAAK,cAAc,WAAWA,wBAAW,SAAS,EAAE,CAAC;AACrD,OAAK,cAAcA,wBAAW,cAAc,KAAK,iBAAiB,KAAK,KAAK;AAC5E,OAAK,cAAcA,wBAAW,sBAC5B,KAAK,eAAe,KAAK,KAAK;AAChC,OAAK,cAAcA,wBAAW,WAAW,KAAK,cAAc,KAAK,KAAK;AACtE,OAAK,cAAcA,wBAAW,sBAC5B,KAAK,aAAa,KAAK,KAAK;AAG9B,OAAK,iBAAiB,IAAIA,yBAAY;AACtC,OAAK,eAAe,WAAWA,wBAAW,UAAU,EAAE,CAAC;AACvD,OAAK,eAAeA,wBAAW,cAC7B,KAAK,kBAAkB,KAAK,KAAK;AACnC,OAAK,eAAeA,wBAAW,sBAC7B,KAAK,gBAAgB,KAAK,KAAK;AACjC,OAAK,eAAeA,wBAAW,WAAW,KAAK,eAAe,KAAK,KAAK;AACxE,OAAK,eAAeA,wBAAW,sBAC7B,KAAK,cAAc,KAAK,KAAK;AAI/B,OAAK,KAAK,gBAAgB,WAAW,KAAK,eAAe,KAAK,CAAC;AAE/D,MAAI,KAAK,QAAQ,aAAa,UAAU;AACtC,WAAQ,IAAI,MAAM,aAAa,KAAK;AAGpC,WAAQ,IAAI,MAAM,cAAc,MAAM;AACtC,WAAQ,IAAI,MAAM,qBAAqB,UAAU;AACjD,WAAQ,IAAI,MAAM,oBAAoB,OAAU;AAChD,WAAQ,IAAI,MAAM,yBAAyB,MAAM;AACjD,WAAQ,IAAI,MAAM,oBAAoB;IACpC,MAAM;IACN,cAAc;IACd,SAAS;IACV,EAAE;;;CAIP,AAAO,KAAK,OAAwB,GAAG,MAAsB;EAC3D,MAAM,YAAY,MAAM,KAAK,KAAK,MAAM,OAAc,GAAG,KAAK;AAE9D,MAAI,KAAK,0BAA0B;AACjC,QAAK,yBAAyB,QAAQ,UAAU;AAChD,UAAO,KAAK,cAAc,MAAM,GAAG;;AAGrC,SAAO,WAAW;;CAGpB,AAAO,QAAQ,OAAiC;AAI9C,aAAW,KAAK,gBAAgB,KAAK;AAErC,MAAI,MACF,MAAK,KAAK,SAAS,MAAM;AAG3B,SAAO,MAAM,QAAQ,MAAM;;;;;;CAO7B,AAAO,cAAoB;AACzB,OAAK,cAAc;AAEnB,MAAI,KAAK,UACP;EAGF,MAAM,SAAS,KAAK,kBAAkB;AACtC,OAAK,iBAAiB;;;;;;;AAQtB,MAAI,aAAa,OACf,QAAO,eAAe,MAAM,WAAW;GACrC,OAAO,OAAO;GACd,YAAY;GACZ,UAAU;GACX,CAAC;AAMJ,OAAK,KAAK,eAAe;AACvB,UAAO,oBAAoB;AAG3B,OAAI,CAAC,OAAO,UACV,QAAO,SAAS;AAGlB,QAAK,iBAAiB;IACtB;AAEF,OAAK,UAAU,OAAO,QAAQ,KAAK,OAAO;EAM1C,IAAIC;EACJ,IAAI,iBAAiB;AAErB,SAAQ,YAAY,KAAK,YAAY,OAAO,CAC1C,KAAI,cAAc,QAAW;AAC3B,OAAI,CAAC,gBAAgB;IACnB,MAAM,CAAC,OAAO,UAAU,YAAY;IACpC,MAAM,cAAc,MAAM,UAAU;IACpC,MAAM,4BAA4B,YAAY,MAC5C,GACA,YAAY,QAAQ,OAAO,GAAG,EAC/B;IACD,MAAM,2BAA2B,YAAY,MAC3C,MAAM,QAAQ,WAAW,CAC1B;IAaD,MAAM,eAAe,GAAG,4BAZE,mBAAmB,KAAK,QAAS,QAAQ,CAGhE,QAAQ,CAAC,UAAU;AAClB,YAAO,KAAK,aAAa,KAAKF;MAC9B,CACD,KAAK,CAAC,MAAM,WAAW,GAAG,KAAK,IAAI,QAAQ,CAC3C,KAAK,OAAO,GAK4D;AAC3E,WAAO,MAAM,cAAc,UAAU,SAAS;AAC9C,qBAAiB;AACjB;;AAGF,UAAO,MAAM,GAAG,UAAU;;AAM9B,MAAI,QAAQ,IAAI,QAAQ,YAAY,CAUlC,CATsB;GACpB;GACA;GACA;GACA;GACA;GACA;GACD,CAEa,SAAS,iBAAiB;AACtC,UAAO,eAAe,MAAM,cAAc;IACxC,YAAY;IACZ,WAAW;KACT,MAAM,QAAQ,QAAQ,IAAI,QAAQ,aAAa;AAC/C,YAAO,OAAO,UAAU,aAAa,MAAM,KAAK,OAAO,GAAG;;IAE7D,CAAC;IACF;AAGJ,SACG,GAAG,WAAW,GAAG,SAAS,KAAK,KAAK,UAAU,GAAG,KAAK,CAAC,CACvD,GAAG,iBAAiB;AACnB,QAAK,aAAa,OAAO;AACzB,QAAK,KAAK,UAAU;IACpB,CACD,GAAG,uBAAuB,KAAK,KAAK,gBAAgB,CAAC,CACrD,GAAG,gBAAgB,KAAK,KAAK,SAAS,CAAC,CACvC,GAAG,YAAY,YAAY,KAAK,KAAK,WAAW,QAAQ,CAAC,CACzD,GAAG,eAAe,KAAK,KAAK,QAAQ,CAAC,CACrC,GAAG,eAAe,KAAK,KAAK,QAAQ,CAAC,CACrC,GAAG,SAAS,UAAU;AAIrB,QAAK,KAAK,MAAM;IAChB,CACD,GAAG,UAAU,UAAU;AACtB,WAAQ,IAAI,MAAM,aAAa,QAAQ,IAAI,QAAQ,YAAY,CAAC;AAChE,QAAK,KAAK,SAAS,MAAM;IACzB,CACD,GAAG,gBAAgB,KAAK,KAAK,SAAS,CAAC,CACvC,GAAG,iBAAiB,KAAK,KAAK,UAAU,CAAC,CACzC,GAAG,mBAAmB,KAAK,KAAK,YAAY,CAAC,CAC7C,GAAG,gBAAgB,KAAK,KAAK,SAAS,CAAC,CACvC,GAAG,UAAU,aAAa,KAAK,KAAK,SAAS,SAAS,CAAC,CACvD,GAAG,aAAa,KAAK,KAAK,MAAM,CAAC;;;;;;CAOtC,MAAa,YAAY,UAAmC;AAG1D,MAAI,KAAK,UACP;AAIF,4BACE,KAAK,gBAAgB,QACrB,oHACA,KAAK,SAAS,QACd,KAAK,SAAS,KACd,SAAS,QACT,SAAS,WACV;AAGD,MAAIG,2CAAqB,UAAU,OAAO,IAAI,SAAS,SAAS,SAAS;AACvE,QAAK,0BAAU,IAAI,UAAU,gBAAgB,CAAC;AAC9C;;AAKF,OAAK,aAAa;AAClB,OAAK,cAAc;AAInB,OAAK,kBAAkB;EAIvB,MAAM,iBAAiB,IAAIC,yBAAe,IAAIC,0BAAgB,KAAK,CAAC;;;;;;;;;AAUpE,iBAAe,aACb,IAAI,WAAW;GACb,QAAQ,OAAO,UAAU,aAAa;AACpC,SAAK,KAAK,OAAO,SAAS;AAC1B,gBAAY;;GAEd,OAAO;GACR,CAAC,CACH;;;;;;;;;;AAWD,iBAAe,aAAa,aAAa;AACzC,iBAAe,aAAa,OAAO;EAEnC,MAAM,qBAAqB,mBAAmB,SAAS,QAAQ;;;;;;AAO/D,iBAAe,UACb,SAAS,QACT,SAAS,cAAcC,uBAAa,SAAS,SAC7C,mBACD;AAGD,OAAK,KAAK,eAAe;AACvB,kBAAe,SAAS;IACxB;AAEF,MAAI,SAAS,KACX,KAAI;GACF,MAAM,SAAS,SAAS,KAAK,WAAW;AAExC,UAAO,MAAM;IACX,MAAM,EAAE,MAAM,UAAU,MAAM,OAAO,MAAM;AAE3C,QAAI,MAAM;AACR,oBAAe,KAAK;AACpB;;AAGF,mBAAe,MAAM,MAAM;;WAEtB,OAAO;AACd,OAAI,iBAAiB,OAAO;AAC1B,mBAAe,SAAS;;;;;AAKxB,SAAK,SAAS;AACd;;AAGF,kBAAe,SAAS;AACxB,SAAM;;MAGR,gBAAe,KAAK;AAItB,MAAI,CAAC,KAAK,iBAAiB;AACzB,QAAK,KAAK,WAAW;;;;;;;;AASrB,QAAK,gBAAgB,KAAK,KAAK;AAC/B,QAAK,KAAK,KAAK;;;;;;CAOnB,AAAO,UAAU,OAAqB;AACpC,OAAK,QAAQ,MAAM;;CAGrB,AAAQ,cAAoB;AAG1B,OAAK,aAAa;EAElB,MAAM,SACJC,iBAAI,OAAO,KAAK,kBAAkB,SAAS,IAC3C,KAAK,kBAAkB,WAAW;EACpC,MAAM,cAAc;GAClB,SAAS,SAAS,QAAQ;GAC1B,QAAQ,SAAS,SAAS;GAC1B,MAAM,KAAK,kBAAkB;GAC9B;AAED,OAAK,gBAAgB;AACrB,OAAK,KACH,UACA,MACA,YAAY,SACZ,YAAY,WAAW,SAAS,IAAI,GACpC,KAAK,kBAAkB,KACxB;AACD,OAAK,KAAK,UAAU;AACpB,OAAK,KAAK,QAAQ;AAElB,MAAI,KAAK,QAAQ,aAAa,UAAU;AACtC,QAAK,KAAK,SAAS;AACnB,QAAK,KAAK,gBAAgB;AAG1B,QAAK,KACH,WACA,KAAK,kBAAkB,WACrB,OAAO,KAAK,2BAA2B,CAC1C;AACD,QAAK,KAAK,WAAW,OAAO,KAAK,sBAAsB,CAAC;;;CAI5D,AAAQ,mBAAyB;AAC/B,OAAK,MAAM,aAAa,KAAK,YAC3B,KAAI,OAAO,UAAU,OAAO,YAAY;AACtC,aAAU,IAAI;;;;;;;AAOd,aAAU,KAAK;;;CA+GrB,AAAQ,cAAc,OAAqB;AACzC,4BACE,KAAK,eACL,6DACD;AAED,OAAK,cAAc,KAAK,MAAM;;CAGhC,AAAQ,eAAqB;AAE3B,MAAI,KAAK,cACP,MAAK,cAAc,KAAK,KAAK;;CA4EjC,AAAQ,eAAe,OAAe;AACpC,4BACE,KAAK,gBACL,8DACD;AAED,OAAK,eAAe,KAAK,MAAM;;CAGjC,AAAQ,gBAAsB;AAE5B,MAAI,KAAK,eACP,MAAK,eAAe,KAAK,KAAK;;;;;;ACnrBpC,IAAa,YAAb,cAA+BC,kBAAK,MAAM;CAKxC,YAAY,SAA2B;AACrC,SAAO;AACP,OAAK,cAAc,QAAQ;AAC3B,OAAK,YAAY,QAAQ;AACzB,OAAK,aAAa,QAAQ;;CAG5B,AAAO,iBAAiB,SAAc,UAA2B;EAC/D,MAAM,mBACJ,KAAK,uBAAuBA,kBAAK,QAC7B,KAAK,YAAY,mBACjB,MAAM;EAEZ,MAAM,0BACJ,KAAK,uBAAuBA,kBAAK,QAC7B;GACE,GAAG;GACH,GAAG,KAAK,YAAY;GACrB,GACD;AAaN,SAXe,IAAI,eAAe;GAChC,mBAAmB;GACnB,kBAAkB,iBAAiB,KACjC,KAAK,eAAe,MACpB,yBACA,SACD;GACD,WAAW,KAAK,UAAU,KAAK,KAAK;GACpC,YAAY,KAAK,WAAW,KAAK,KAAK;GACvC,CAAC;;;AAMN,IAAa,iBAAb,cAAoCC,mBAAM,MAAM;CAK9C,YAAY,SAA2B;AACrC,SAAO;AACP,OAAK,cAAc,QAAQ;AAC3B,OAAK,YAAY,QAAQ;AACzB,OAAK,aAAa,QAAQ;;CAG5B,AAAO,iBAAiB,SAAc,UAA2B;EAC/D,MAAM,mBACJ,KAAK,uBAAuBD,kBAAK,QAC7B,KAAK,YAAY,mBACjB,MAAM;EAEZ,MAAM,0BACJ,KAAK,uBAAuBA,kBAAK,QAC7B;GACE,GAAG;GACH,GAAG,KAAK,YAAY;GACrB,GACD;AAaN,SAXe,IAAI,eAAe;GAChC,mBAAmB;GACnB,kBAAkB,iBAAiB,KACjC,KAAK,eAAe,MACpB,yBACA,SACD;GACD,WAAW,KAAK,UAAU,KAAK,KAAK;GACpC,YAAY,KAAK,WAAW,KAAK,KAAK;GACvC,CAAC;;;;;;ACrGN,MAAME,WAAS,IAAIC,0BAAO,+BAA+B;AAWzD,MAAa,eAAe;AAC5B,MAAM,mBAAmB;AACzB,MAAM,mBAAmB;AACzB,MAAM,WAAW;AAEjB,SAAS,SACP,SACgC;AAChC,QAAO,QAAQ,iBAAiBC,aAAQ,QAAQ,QAAQ;;AAG1D,SAAS,4BAA4B,SAAyC;AAC5E,KAAI,QAAQ,SACV,QAAO,QAAQ;CAIjB,MAAM,gBADQ,SAAS,QAAQ,EACkB;AAEjD,KAAI,cACF,QAAO;CAGT,MAAM,OAAO,wBAAwB,QAAQ;AAG7C,QAFwB,QAAQ,QAAQ,SAAS,WAExB,WAAW,QAAQ,KAAK,YAAY;;AAG/D,SAAS,wBACP,SACoB;AAEpB,KAAI,QAAQ,KACV,QAAO,OAAO,QAAQ,KAAK;CAI7B,MAAM,QAAQ,SAAS,QAAQ;AAE/B,KAAK,OAAsB,QAAQ,KACjC,QAAO,OAAQ,MAAqB,QAAQ,KAAK;AAGnD,KAAK,OAA0B,YAC7B,QAAO,OAAQ,MAAyB,YAAY;;AAaxD,SAAS,wBACP,SACyB;AACzB,KAAI,QAAQ,MAAM;EAChB,MAAM,CAAC,UAAU,YAAY,QAAQ,KAAK,MAAM,IAAI;AACpD,SAAO;GAAE;GAAU;GAAU;;;;;;;;AASjC,SAAS,iBAAiB,MAAuB;AAC/C,QAAO,KAAK,SAAS,IAAI,IAAI,CAAC,KAAK,WAAW,IAAI,IAAI,CAAC,KAAK,SAAS,IAAI;;AAG3E,SAAS,YAAY,SAAqD;CACxE,IAAI,OAAO,QAAQ,YAAY,QAAQ;AAEvC,KAAI,MAAM;AACR,MAAI,iBAAiB,KAAK,CACvB,QAAO,IAAI,KAAK;AAKnB,SAAO,IAAI,IAAI,UAAU,OAAO,CAAC;;AAGnC,QAAO;;;;;AAMT,SAAgB,uBAAuB,SAAsC;AAC3E,UAAO,KAAK,mBAAmB,QAAQ;AAEvC,KAAI,QAAQ,KAAK;AACf,WAAO,KACL,iEACA,QAAQ,IACT;AACD,SAAO,IAAI,IAAI,QAAQ,IAAI,KAAK;;AAGlC,UAAO,KAAK,2CAA2C;CAEvD,MAAM,WAAW,4BAA4B,QAAQ;AACrD,UAAO,KAAK,YAAY,SAAS;CAEjC,MAAM,OAAO,wBAAwB,QAAQ;AAC7C,UAAO,KAAK,QAAQ,KAAK;CAEzB,MAAM,WAAW,YAAY,QAAQ;AACrC,UAAO,KAAK,YAAY,SAAS;CAEjC,MAAM,OAAO,QAAQ,QAAQ;AAC7B,UAAO,KAAK,QAAQ,KAAK;CAEzB,MAAM,cAAc,wBAAwB,QAAQ;AACpD,UAAO,KAAK,eAAe,YAAY;CAEvC,MAAM,aAAa,cACf,GAAG,YAAY,SAAS,GAAG,YAAY,SAAS,KAChD;AACJ,UAAO,KAAK,gBAAgB,WAAW;CAEvC,MAAM,aAAa,OAAO,SAAS,cAAc,IAAI,SAAS;CAC9D,MAAM,MAAM,IAAI,IAAI,GAAG,SAAS,IAAI,WAAW,aAAa,OAAO;AACnE,KAAI,WAAW,aAAa,YAAY;AACxC,KAAI,WAAW,aAAa,YAAY;AAExC,UAAO,KAAK,gBAAgB,IAAI;AAEhC,QAAO;;;;;ACpJT,MAAMC,WAAS,IAAIC,0BAAO,cAAc;AAExC,SAAS,cAAc,KAAoC;AACzD,UAAO,KAAK,oBAAoB,IAAI;AAEpC,KAAI,OAAO,QAAQ,CAAC,IAAI,aAAa,MAAM;AACzC,WAAO,KAAK,mDAAmD;AAC/D,SAAO;;AAGT,UAAO,KAAK,oCAAoC,IAAI,YAAY,KAAK;AACrE,QAAO,IAAI,YAAY,SAAS;;AAGlC,SAAgB,YACd,KACY;AACZ,UAAO,KAAK,mBAAmB,IAAI;CAEnC,MAAM,uBAAuB,OAAO,QAAQ,IAAI,CAAC,QAC9C,KAAK,CAAC,KAAK,WAAW;AACrB,WAAO,KAAK,6BAA6B,KAAK,MAAM;AAGpD,MAAI,OAAO,cAAc,MAAM,GAAG,YAAY,MAAM,GAAG;AACvD,SAAO;IAET,EAAE,CACH;AAED,QAAO,cAAc,IAAI,GACrB,uBACA,OAAO,OAAO,OAAO,eAAe,IAAI,EAAE,qBAAqB;;;;;ACJrE,MAAM,SAAS,IAAIC,0BAAO,kCAAkC;AAW5D,SAAS,sBACP,MACA,KACgB;AAGhB,KAAI,OAAO,KAAK,OAAO,eAAe,OAAO,KAAK,OAAO,YAAY;AACnE,SAAO,KAAK,uDAAuD,IAAI;AACvE,wCAAwB,IAAI;;AAG9B,KAAI,KAAK,IAAI;AACX,SAAO,KAAK,8BAA8B,KAAK,GAAG;EAClD,MAAM,uDAAyC,IAAI;AAEnD,SAAO,KAAK,wCAAwC,sBAAsB;;;;;;AAO1E,SAAO,KAAK,4BAA4B;EACxC,MAAM,uBAAuB,YAAY,KAAK,GAAG;AACjD,SAAO,KAAK,uCAAuC,qBAAqB;AAExE,SAAO;GACL,GAAG;GACH,GAAG;GACJ;;AAGH,QAAO,KAAK,2CAA2C;AACvD,QAAO,EAAE;;;;;;;AAQX,SAAS,4BAA4B,KAAU,SAA8B;AAC3E,KAAI,OAAO,QAAQ,QAAQ,IAAI;AAC/B,KAAI,WAAW,QAAQ,YAAY,IAAI;AACvC,KAAI,OAAO,QAAQ,OAAO,QAAQ,KAAK,UAAU,GAAG,IAAI;AAExD,KAAI,QAAQ,MAAM;EAChB,MAAM,wCAA6B,QAAQ,MAAM,MAAM;AACvD,MAAI,WAAW,kBAAkB,YAAY;AAC7C,MAAI,SAAS,kBAAkB,UAAU;;AAG3C,QAAO;;AAGT,SAAS,gBACP,MACiC;AACjC,QAAO,OAAO,KAAK,OAAO,aAAa,KAAK,KAAK,KAAK;;;;;;AAaxD,SAAgB,2BACd,iBACA,MAC6B;CAC7B,IAAIC;CACJ,IAAIC;CACJ,IAAIC;AAEJ,QAAO,KAAK,aAAa,KAAK;AAC9B,QAAO,KAAK,2BAA2B,gBAAgB;AAIvD,KAAI,KAAK,WAAW,GAAG;EACrB,MAAMC,QAAM,IAAIC,aAAI,mBAAmB;AAEvC,SAAO,CAACD,OADQ,sBAAsB,MAAMA,MAAI,CAC3B;;AAKvB,KAAI,OAAO,KAAK,OAAO,UAAU;AAC/B,SAAO,KAAK,wCAAwC,KAAK,GAAG;AAE5D,QAAM,IAAIC,aAAI,KAAK,GAAG;AACtB,SAAO,KAAK,kBAAkB,IAAI;EAElC,MAAM,uDAAyC,IAAI;AACnD,SAAO,KAAK,6BAA6B,sBAAsB;AAE/D,YAAU,sBAAsB,MAAM,IAAI;AAC1C,SAAO,KAAK,6BAA6B,QAAQ;AAEjD,aAAW,gBAAgB,KAAK;YAIzB,KAAK,cAAcA,cAAK;AAC/B,QAAM,KAAK;AACX,SAAO,KAAK,4BAA4B,IAAI;AAO5C,MAAI,OAAO,KAAK,OAAO,eAAeC,+BAAyB,KAAK,GAAG,CACrE,OAAM,4BAA4B,KAAK,KAAK,GAAG;AAGjD,YAAU,sBAAsB,MAAM,IAAI;AAC1C,SAAO,KAAK,4BAA4B,QAAQ;AAEhD,aAAW,gBAAgB,KAAK;YAIzB,UAAU,KAAK,MAAM,EAAE,YAAY,KAAK,KAAK;EACpD,MAAM,CAAC,aAAa;AACpB,SAAO,KAAK,mCAAmC,UAAU;AAEzD,MAAI,UAAU,aAAa,MAAM;;;;;;;;AAQ/B,UAAO,KAAK,6CAA6C;AAEzD,UAAOA,+BAAS,KAAK,GAAG,GACpB,2BAA2B,iBAAiB,CAC1C;IAAE,MAAM,UAAU;IAAM,GAAG,KAAK;IAAI,EACpC,KAAK,GACN,CAAC,GACF,2BAA2B,iBAAiB,CAC1C,EAAE,MAAM,UAAU,MAAM,EACxB,KAAK,GACN,CAAC;;AAGR,SAAO,KAAK,+BAA+B;EAG3C,MAAM,cAAc,IAAID,aAAI,UAAU,KAAK;AAE3C,SAAO,KAAK,OAAO,SACf,2BAA2B,iBAAiB,CAAC,YAAY,CAAC,GAC1D,OAAO,KAAK,OAAO,aACnB,2BAA2B,iBAAiB,CAAC,aAAa,KAAK,GAAG,CAAC,GACnE,2BAA2B,iBAAiB;GAC1C;GACA,KAAK;GACL,KAAK;GACN,CAAC;YAICC,+BAAS,KAAK,GAAG,EAAE;AAC1B,YAAU,EAAE,GAAI,KAAK,IAAY;AACjC,SAAO,KAAK,qCAAqC,QAAQ;AAIzD,UAAQ,WAAW,QAAQ,YAAY;AACvC,SAAO,KAAK,+BAA+B,QAAQ;AAEnD,QAAM,uBAAuB,QAAQ;AACrC,SAAO,KAAK,sCAAsC,IAAI,KAAK;AAE3D,aAAW,gBAAgB,KAAK;OAEhC,OAAM,IAAI,MACR,4DAA4D,OAC7D;AAGH,SAAQ,WAAW,QAAQ,YAAY,IAAI;AAC3C,SAAQ,SAAS,QAAQ,UAAU;;;;;;;;;AAUnC,KAAI,CAAC,QAAQ,eAAe;AAC1B,SAAO,KACL,8DACA,QAAQ,SACT;AAED,UAAQ,gBACN,QAAQ,aAAa,WAAWC,yBAAmBC;;AAGvD,QAAO,KAAK,8BAA8B,IAAI,KAAK;AACnD,QAAO,KAAK,kCAAkC,QAAQ;AACtD,QAAO,KAAK,mCAAmC,SAAS;;;;;;;;AASxD,KAAI,EAAE,eAAeH,cACnB,OAAO,IAAY,UAAU;AAG/B,QAAO;EAAC;EAAK;EAAS;EAAS;;;;;ACvPjC,IAAa,2BAAb,MAAa,iCAAiCI,+BAAiC;;gBAC7D,OAAO,6BAA6B;;CAEpD,cAAc;AACZ,QAAM,yBAAyB,OAAO;mBAgIW,OAAO,EACxD,SACA,aACI;GACJ,MAAM,aAAa,IAAIC,qCAAkB,SAAS;IAChD,cAAc;AACZ,YAAO,aAAa;;IAEtB,MAAM,YAAY,UAAU;AAC1B,WAAM,OAAO,YAAY,SAAS;;IAEpC,UAAU,QAAQ;AAChB,SAAI,kBAAkB,MACpB,QAAO,UAAU,OAAO;;IAG7B,CAAC;AAEF,SAAMC,oCAAc;IAClB;IACA,WAAW,QAAQ,IAAI,SAAS,WAAW;IAC3C;IACA,SAAS,KAAK;IACf,CAAC;;oBAGgD,OAAO,EACzD,WACA,SACA,UACA,uBACI;AAGJ,UAAOC,gCAAU,KAAK,SAAS,YAAY;IACzC;IACA;IACA;IACA;IACD,CAAC;;;CApKJ,AAAU,QAAc;EACtB,MAAM,EACJ,eAAe,uBACf,KAAK,aACL,SAAS,oBACPC;EACJ,MAAM,EAAE,KAAK,kBAAkB,SAAS,yBAAyBC;EAEjE,MAAM,YAAY,KAAK,UAAU,KAAK,KAAK;EAC3C,MAAM,aAAa,KAAK,WAAW,KAAK,KAAK;AAG7C,oBAAK,gBAAgB,IAAI,MAAMD,kBAAK,eAAe,EACjD,YAAY,QAAQ,SAA0C;GAC5D,MAAM,CAAC,KAAK,SAAS,YAAY,2BAC/B,SACA,KACD;AASD,WAAQ,QALU,KADJ,QAAQ,aAAa,WAAW,iBAAiB,WACnC;IAC1B,aAAa,QAAQ;IACrB;IACA;IACD,CAAC;AAGF,UAAO,QAAQ,UAAU,QAAQ;IAAC;IAAK;IAAS;IAAS,CAAC;KAE7D,CAAC;AAEF,oBAAK,UAAU,IAAI,MAAMA,kBAAK,SAAS,EACrC,QAAQ,QAAQ,SAAS,SAA0C;GACjE,MAAM,CAAC,KAAK,SAAS,YAAY,2BAC/B,SACA,KACD;AAMD,WAAQ,QALU,IAAI,UAAU;IAC9B,aAAa,QAAQ;IACrB;IACA;IACD,CAAC;AAGF,UAAO,QAAQ,MAAM,QAAQ,SAAS;IAAC;IAAK;IAAS;IAAS,CAAC;KAElE,CAAC;AAEF,oBAAK,MAAM,IAAI,MAAMA,kBAAK,KAAK,EAC7B,QAAQ,QAAQ,SAAS,SAAsC;GAC7D,MAAM,CAAC,KAAK,SAAS,YAAY,2BAC/B,SACA,KACD;AAOD,WAAQ,QALU,IAAI,UAAU;IAC9B,aAAa,QAAQ;IACrB;IACA;IACD,CAAC;AAGF,UAAO,QAAQ,MAAM,QAAQ,SAAS;IAAC;IAAK;IAAS;IAAS,CAAC;KAElE,CAAC;AAMF,qBAAM,UAAU,IAAI,MAAMC,mBAAM,SAAS,EACvC,QAAQ,QAAQ,SAAS,SAA2C;GAClE,MAAM,CAAC,KAAK,SAAS,YAAY,2BAC/B,UACA,KACD;AAOD,WAAQ,QALU,IAAI,eAAe;IACnC,aAAa,QAAQ;IACrB;IACA;IACD,CAAC;AAGF,UAAO,QAAQ,MAAM,QAAQ,SAAS;IAAC;IAAK;IAAS;IAAS,CAAC;KAElE,CAAC;AAEF,qBAAM,MAAM,IAAI,MAAMA,mBAAM,KAAK,EAC/B,QAAQ,QAAQ,SAAS,SAAuC;GAC9D,MAAM,CAAC,KAAK,SAAS,YAAY,2BAC/B,UACA,KACD;AAOD,WAAQ,QALU,IAAI,eAAe;IACnC,aAAa,QAAQ;IACrB;IACA;IACD,CAAC;AAGF,UAAO,QAAQ,MAAM,QAAQ,SAAS;IAAC;IAAK;IAAS;IAAS,CAAC;KAElE,CAAC;AAKF,yBAAuB;AAEvB,OAAK,cAAc,WAAW;AAC5B,qBAAK,gBAAgB;AAErB,qBAAK,MAAM;AACX,qBAAK,UAAU;AAEf,sBAAM,MAAM;AACZ,sBAAM,UAAU;AAEhB,4BAAyB;IACzB"}