1 line
105 KiB
JSON
1 line
105 KiB
JSON
{"ast":null,"code":"/* eslint no-unused-vars: [\"error\", { \"varsIgnorePattern\": \"^Duplex|Readable$\", \"caughtErrors\": \"none\" }] */\n\n'use strict';\n\nconst EventEmitter = require('events');\nconst https = require('https');\nconst http = require('http');\nconst net = require('net');\nconst tls = require('tls');\nconst {\n randomBytes,\n createHash\n} = require('crypto');\nconst {\n Duplex,\n Readable\n} = require('stream');\nconst {\n URL\n} = require('url');\nconst PerMessageDeflate = require('./permessage-deflate');\nconst Receiver = require('./receiver');\nconst Sender = require('./sender');\nconst {\n isBlob\n} = require('./validation');\nconst {\n BINARY_TYPES,\n EMPTY_BUFFER,\n GUID,\n kForOnEventAttribute,\n kListener,\n kStatusCode,\n kWebSocket,\n NOOP\n} = require('./constants');\nconst {\n EventTarget: {\n addEventListener,\n removeEventListener\n }\n} = require('./event-target');\nconst {\n format,\n parse\n} = require('./extension');\nconst {\n toBuffer\n} = require('./buffer-util');\nconst closeTimeout = 30 * 1000;\nconst kAborted = Symbol('kAborted');\nconst protocolVersions = [8, 13];\nconst readyStates = ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED'];\nconst subprotocolRegex = /^[!#$%&'*+\\-.0-9A-Z^_`|a-z~]+$/;\n\n/**\n * Class representing a WebSocket.\n *\n * @extends EventEmitter\n */\nclass WebSocket extends EventEmitter {\n /**\n * Create a new `WebSocket`.\n *\n * @param {(String|URL)} address The URL to which to connect\n * @param {(String|String[])} [protocols] The subprotocols\n * @param {Object} [options] Connection options\n */\n constructor(address, protocols, options) {\n super();\n this._binaryType = BINARY_TYPES[0];\n this._closeCode = 1006;\n this._closeFrameReceived = false;\n this._closeFrameSent = false;\n this._closeMessage = EMPTY_BUFFER;\n this._closeTimer = null;\n this._errorEmitted = false;\n this._extensions = {};\n this._paused = false;\n this._protocol = '';\n this._readyState = WebSocket.CONNECTING;\n this._receiver = null;\n this._sender = null;\n this._socket = null;\n if (address !== null) {\n this._bufferedAmount = 0;\n this._isServer = false;\n this._redirects = 0;\n if (protocols === undefined) {\n protocols = [];\n } else if (!Array.isArray(protocols)) {\n if (typeof protocols === 'object' && protocols !== null) {\n options = protocols;\n protocols = [];\n } else {\n protocols = [protocols];\n }\n }\n initAsClient(this, address, protocols, options);\n } else {\n this._autoPong = options.autoPong;\n this._isServer = true;\n }\n }\n\n /**\n * For historical reasons, the custom \"nodebuffer\" type is used by the default\n * instead of \"blob\".\n *\n * @type {String}\n */\n get binaryType() {\n return this._binaryType;\n }\n set binaryType(type) {\n if (!BINARY_TYPES.includes(type)) return;\n this._binaryType = type;\n\n //\n // Allow to change `binaryType` on the fly.\n //\n if (this._receiver) this._receiver._binaryType = type;\n }\n\n /**\n * @type {Number}\n */\n get bufferedAmount() {\n if (!this._socket) return this._bufferedAmount;\n return this._socket._writableState.length + this._sender._bufferedBytes;\n }\n\n /**\n * @type {String}\n */\n get extensions() {\n return Object.keys(this._extensions).join();\n }\n\n /**\n * @type {Boolean}\n */\n get isPaused() {\n return this._paused;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onclose() {\n return null;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onerror() {\n return null;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onopen() {\n return null;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onmessage() {\n return null;\n }\n\n /**\n * @type {String}\n */\n get protocol() {\n return this._protocol;\n }\n\n /**\n * @type {Number}\n */\n get readyState() {\n return this._readyState;\n }\n\n /**\n * @type {String}\n */\n get url() {\n return this._url;\n }\n\n /**\n * Set up the socket and the internal resources.\n *\n * @param {Duplex} socket The network socket between the server and client\n * @param {Buffer} head The first packet of the upgraded stream\n * @param {Object} options Options object\n * @param {Boolean} [options.allowSynchronousEvents=false] Specifies whether\n * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted\n * multiple times in the same tick\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Number} [options.maxPayload=0] The maximum allowed message size\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n * @private\n */\n setSocket(socket, head, options) {\n const receiver = new Receiver({\n allowSynchronousEvents: options.allowSynchronousEvents,\n binaryType: this.binaryType,\n extensions: this._extensions,\n isServer: this._isServer,\n maxPayload: options.maxPayload,\n skipUTF8Validation: options.skipUTF8Validation\n });\n const sender = new Sender(socket, this._extensions, options.generateMask);\n this._receiver = receiver;\n this._sender = sender;\n this._socket = socket;\n receiver[kWebSocket] = this;\n sender[kWebSocket] = this;\n socket[kWebSocket] = this;\n receiver.on('conclude', receiverOnConclude);\n receiver.on('drain', receiverOnDrain);\n receiver.on('error', receiverOnError);\n receiver.on('message', receiverOnMessage);\n receiver.on('ping', receiverOnPing);\n receiver.on('pong', receiverOnPong);\n sender.onerror = senderOnError;\n\n //\n // These methods may not be available if `socket` is just a `Duplex`.\n //\n if (socket.setTimeout) socket.setTimeout(0);\n if (socket.setNoDelay) socket.setNoDelay();\n if (head.length > 0) socket.unshift(head);\n socket.on('close', socketOnClose);\n socket.on('data', socketOnData);\n socket.on('end', socketOnEnd);\n socket.on('error', socketOnError);\n this._readyState = WebSocket.OPEN;\n this.emit('open');\n }\n\n /**\n * Emit the `'close'` event.\n *\n * @private\n */\n emitClose() {\n if (!this._socket) {\n this._readyState = WebSocket.CLOSED;\n this.emit('close', this._closeCode, this._closeMessage);\n return;\n }\n if (this._extensions[PerMessageDeflate.extensionName]) {\n this._extensions[PerMessageDeflate.extensionName].cleanup();\n }\n this._receiver.removeAllListeners();\n this._readyState = WebSocket.CLOSED;\n this.emit('close', this._closeCode, this._closeMessage);\n }\n\n /**\n * Start a closing handshake.\n *\n * +----------+ +-----------+ +----------+\n * - - -|ws.close()|-->|close frame|-->|ws.close()|- - -\n * | +----------+ +-----------+ +----------+ |\n * +----------+ +-----------+ |\n * CLOSING |ws.close()|<--|close frame|<--+-----+ CLOSING\n * +----------+ +-----------+ |\n * | | | +---+ |\n * +------------------------+-->|fin| - - - -\n * | +---+ | +---+\n * - - - - -|fin|<---------------------+\n * +---+\n *\n * @param {Number} [code] Status code explaining why the connection is closing\n * @param {(String|Buffer)} [data] The reason why the connection is\n * closing\n * @public\n */\n close(code, data) {\n if (this.readyState === WebSocket.CLOSED) return;\n if (this.readyState === WebSocket.CONNECTING) {\n const msg = 'WebSocket was closed before the connection was established';\n abortHandshake(this, this._req, msg);\n return;\n }\n if (this.readyState === WebSocket.CLOSING) {\n if (this._closeFrameSent && (this._closeFrameReceived || this._receiver._writableState.errorEmitted)) {\n this._socket.end();\n }\n return;\n }\n this._readyState = WebSocket.CLOSING;\n this._sender.close(code, data, !this._isServer, err => {\n //\n // This error is handled by the `'error'` listener on the socket. We only\n // want to know if the close frame has been sent here.\n //\n if (err) return;\n this._closeFrameSent = true;\n if (this._closeFrameReceived || this._receiver._writableState.errorEmitted) {\n this._socket.end();\n }\n });\n setCloseTimer(this);\n }\n\n /**\n * Pause the socket.\n *\n * @public\n */\n pause() {\n if (this.readyState === WebSocket.CONNECTING || this.readyState === WebSocket.CLOSED) {\n return;\n }\n this._paused = true;\n this._socket.pause();\n }\n\n /**\n * Send a ping.\n *\n * @param {*} [data] The data to send\n * @param {Boolean} [mask] Indicates whether or not to mask `data`\n * @param {Function} [cb] Callback which is executed when the ping is sent\n * @public\n */\n ping(data, mask, cb) {\n if (this.readyState === WebSocket.CONNECTING) {\n throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');\n }\n if (typeof data === 'function') {\n cb = data;\n data = mask = undefined;\n } else if (typeof mask === 'function') {\n cb = mask;\n mask = undefined;\n }\n if (typeof data === 'number') data = data.toString();\n if (this.readyState !== WebSocket.OPEN) {\n sendAfterClose(this, data, cb);\n return;\n }\n if (mask === undefined) mask = !this._isServer;\n this._sender.ping(data || EMPTY_BUFFER, mask, cb);\n }\n\n /**\n * Send a pong.\n *\n * @param {*} [data] The data to send\n * @param {Boolean} [mask] Indicates whether or not to mask `data`\n * @param {Function} [cb] Callback which is executed when the pong is sent\n * @public\n */\n pong(data, mask, cb) {\n if (this.readyState === WebSocket.CONNECTING) {\n throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');\n }\n if (typeof data === 'function') {\n cb = data;\n data = mask = undefined;\n } else if (typeof mask === 'function') {\n cb = mask;\n mask = undefined;\n }\n if (typeof data === 'number') data = data.toString();\n if (this.readyState !== WebSocket.OPEN) {\n sendAfterClose(this, data, cb);\n return;\n }\n if (mask === undefined) mask = !this._isServer;\n this._sender.pong(data || EMPTY_BUFFER, mask, cb);\n }\n\n /**\n * Resume the socket.\n *\n * @public\n */\n resume() {\n if (this.readyState === WebSocket.CONNECTING || this.readyState === WebSocket.CLOSED) {\n return;\n }\n this._paused = false;\n if (!this._receiver._writableState.needDrain) this._socket.resume();\n }\n\n /**\n * Send a data message.\n *\n * @param {*} data The message to send\n * @param {Object} [options] Options object\n * @param {Boolean} [options.binary] Specifies whether `data` is binary or\n * text\n * @param {Boolean} [options.compress] Specifies whether or not to compress\n * `data`\n * @param {Boolean} [options.fin=true] Specifies whether the fragment is the\n * last one\n * @param {Boolean} [options.mask] Specifies whether or not to mask `data`\n * @param {Function} [cb] Callback which is executed when data is written out\n * @public\n */\n send(data, options, cb) {\n if (this.readyState === WebSocket.CONNECTING) {\n throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');\n }\n if (typeof options === 'function') {\n cb = options;\n options = {};\n }\n if (typeof data === 'number') data = data.toString();\n if (this.readyState !== WebSocket.OPEN) {\n sendAfterClose(this, data, cb);\n return;\n }\n const opts = {\n binary: typeof data !== 'string',\n mask: !this._isServer,\n compress: true,\n fin: true,\n ...options\n };\n if (!this._extensions[PerMessageDeflate.extensionName]) {\n opts.compress = false;\n }\n this._sender.send(data || EMPTY_BUFFER, opts, cb);\n }\n\n /**\n * Forcibly close the connection.\n *\n * @public\n */\n terminate() {\n if (this.readyState === WebSocket.CLOSED) return;\n if (this.readyState === WebSocket.CONNECTING) {\n const msg = 'WebSocket was closed before the connection was established';\n abortHandshake(this, this._req, msg);\n return;\n }\n if (this._socket) {\n this._readyState = WebSocket.CLOSING;\n this._socket.destroy();\n }\n }\n}\n\n/**\n * @constant {Number} CONNECTING\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'CONNECTING', {\n enumerable: true,\n value: readyStates.indexOf('CONNECTING')\n});\n\n/**\n * @constant {Number} CONNECTING\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'CONNECTING', {\n enumerable: true,\n value: readyStates.indexOf('CONNECTING')\n});\n\n/**\n * @constant {Number} OPEN\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'OPEN', {\n enumerable: true,\n value: readyStates.indexOf('OPEN')\n});\n\n/**\n * @constant {Number} OPEN\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'OPEN', {\n enumerable: true,\n value: readyStates.indexOf('OPEN')\n});\n\n/**\n * @constant {Number} CLOSING\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'CLOSING', {\n enumerable: true,\n value: readyStates.indexOf('CLOSING')\n});\n\n/**\n * @constant {Number} CLOSING\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'CLOSING', {\n enumerable: true,\n value: readyStates.indexOf('CLOSING')\n});\n\n/**\n * @constant {Number} CLOSED\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'CLOSED', {\n enumerable: true,\n value: readyStates.indexOf('CLOSED')\n});\n\n/**\n * @constant {Number} CLOSED\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'CLOSED', {\n enumerable: true,\n value: readyStates.indexOf('CLOSED')\n});\n['binaryType', 'bufferedAmount', 'extensions', 'isPaused', 'protocol', 'readyState', 'url'].forEach(property => {\n Object.defineProperty(WebSocket.prototype, property, {\n enumerable: true\n });\n});\n\n//\n// Add the `onopen`, `onerror`, `onclose`, and `onmessage` attributes.\n// See https://html.spec.whatwg.org/multipage/comms.html#the-websocket-interface\n//\n['open', 'error', 'close', 'message'].forEach(method => {\n Object.defineProperty(WebSocket.prototype, `on${method}`, {\n enumerable: true,\n get() {\n for (const listener of this.listeners(method)) {\n if (listener[kForOnEventAttribute]) return listener[kListener];\n }\n return null;\n },\n set(handler) {\n for (const listener of this.listeners(method)) {\n if (listener[kForOnEventAttribute]) {\n this.removeListener(method, listener);\n break;\n }\n }\n if (typeof handler !== 'function') return;\n this.addEventListener(method, handler, {\n [kForOnEventAttribute]: true\n });\n }\n });\n});\nWebSocket.prototype.addEventListener = addEventListener;\nWebSocket.prototype.removeEventListener = removeEventListener;\nmodule.exports = WebSocket;\n\n/**\n * Initialize a WebSocket client.\n *\n * @param {WebSocket} websocket The client to initialize\n * @param {(String|URL)} address The URL to which to connect\n * @param {Array} protocols The subprotocols\n * @param {Object} [options] Connection options\n * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether any\n * of the `'message'`, `'ping'`, and `'pong'` events can be emitted multiple\n * times in the same tick\n * @param {Boolean} [options.autoPong=true] Specifies whether or not to\n * automatically send a pong in response to a ping\n * @param {Function} [options.finishRequest] A function which can be used to\n * customize the headers of each http request before it is sent\n * @param {Boolean} [options.followRedirects=false] Whether or not to follow\n * redirects\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Number} [options.handshakeTimeout] Timeout in milliseconds for the\n * handshake request\n * @param {Number} [options.maxPayload=104857600] The maximum allowed message\n * size\n * @param {Number} [options.maxRedirects=10] The maximum number of redirects\n * allowed\n * @param {String} [options.origin] Value of the `Origin` or\n * `Sec-WebSocket-Origin` header\n * @param {(Boolean|Object)} [options.perMessageDeflate=true] Enable/disable\n * permessage-deflate\n * @param {Number} [options.protocolVersion=13] Value of the\n * `Sec-WebSocket-Version` header\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n * @private\n */\nfunction initAsClient(websocket, address, protocols, options) {\n const opts = {\n allowSynchronousEvents: true,\n autoPong: true,\n protocolVersion: protocolVersions[1],\n maxPayload: 100 * 1024 * 1024,\n skipUTF8Validation: false,\n perMessageDeflate: true,\n followRedirects: false,\n maxRedirects: 10,\n ...options,\n socketPath: undefined,\n hostname: undefined,\n protocol: undefined,\n timeout: undefined,\n method: 'GET',\n host: undefined,\n path: undefined,\n port: undefined\n };\n websocket._autoPong = opts.autoPong;\n if (!protocolVersions.includes(opts.protocolVersion)) {\n throw new RangeError(`Unsupported protocol version: ${opts.protocolVersion} ` + `(supported versions: ${protocolVersions.join(', ')})`);\n }\n let parsedUrl;\n if (address instanceof URL) {\n parsedUrl = address;\n } else {\n try {\n parsedUrl = new URL(address);\n } catch (e) {\n throw new SyntaxError(`Invalid URL: ${address}`);\n }\n }\n if (parsedUrl.protocol === 'http:') {\n parsedUrl.protocol = 'ws:';\n } else if (parsedUrl.protocol === 'https:') {\n parsedUrl.protocol = 'wss:';\n }\n websocket._url = parsedUrl.href;\n const isSecure = parsedUrl.protocol === 'wss:';\n const isIpcUrl = parsedUrl.protocol === 'ws+unix:';\n let invalidUrlMessage;\n if (parsedUrl.protocol !== 'ws:' && !isSecure && !isIpcUrl) {\n invalidUrlMessage = 'The URL\\'s protocol must be one of \"ws:\", \"wss:\", ' + '\"http:\", \"https\", or \"ws+unix:\"';\n } else if (isIpcUrl && !parsedUrl.pathname) {\n invalidUrlMessage = \"The URL's pathname is empty\";\n } else if (parsedUrl.hash) {\n invalidUrlMessage = 'The URL contains a fragment identifier';\n }\n if (invalidUrlMessage) {\n const err = new SyntaxError(invalidUrlMessage);\n if (websocket._redirects === 0) {\n throw err;\n } else {\n emitErrorAndClose(websocket, err);\n return;\n }\n }\n const defaultPort = isSecure ? 443 : 80;\n const key = randomBytes(16).toString('base64');\n const request = isSecure ? https.request : http.request;\n const protocolSet = new Set();\n let perMessageDeflate;\n opts.createConnection = opts.createConnection || (isSecure ? tlsConnect : netConnect);\n opts.defaultPort = opts.defaultPort || defaultPort;\n opts.port = parsedUrl.port || defaultPort;\n opts.host = parsedUrl.hostname.startsWith('[') ? parsedUrl.hostname.slice(1, -1) : parsedUrl.hostname;\n opts.headers = {\n ...opts.headers,\n 'Sec-WebSocket-Version': opts.protocolVersion,\n 'Sec-WebSocket-Key': key,\n Connection: 'Upgrade',\n Upgrade: 'websocket'\n };\n opts.path = parsedUrl.pathname + parsedUrl.search;\n opts.timeout = opts.handshakeTimeout;\n if (opts.perMessageDeflate) {\n perMessageDeflate = new PerMessageDeflate(opts.perMessageDeflate !== true ? opts.perMessageDeflate : {}, false, opts.maxPayload);\n opts.headers['Sec-WebSocket-Extensions'] = format({\n [PerMessageDeflate.extensionName]: perMessageDeflate.offer()\n });\n }\n if (protocols.length) {\n for (const protocol of protocols) {\n if (typeof protocol !== 'string' || !subprotocolRegex.test(protocol) || protocolSet.has(protocol)) {\n throw new SyntaxError('An invalid or duplicated subprotocol was specified');\n }\n protocolSet.add(protocol);\n }\n opts.headers['Sec-WebSocket-Protocol'] = protocols.join(',');\n }\n if (opts.origin) {\n if (opts.protocolVersion < 13) {\n opts.headers['Sec-WebSocket-Origin'] = opts.origin;\n } else {\n opts.headers.Origin = opts.origin;\n }\n }\n if (parsedUrl.username || parsedUrl.password) {\n opts.auth = `${parsedUrl.username}:${parsedUrl.password}`;\n }\n if (isIpcUrl) {\n const parts = opts.path.split(':');\n opts.socketPath = parts[0];\n opts.path = parts[1];\n }\n let req;\n if (opts.followRedirects) {\n if (websocket._redirects === 0) {\n websocket._originalIpc = isIpcUrl;\n websocket._originalSecure = isSecure;\n websocket._originalHostOrSocketPath = isIpcUrl ? opts.socketPath : parsedUrl.host;\n const headers = options && options.headers;\n\n //\n // Shallow copy the user provided options so that headers can be changed\n // without mutating the original object.\n //\n options = {\n ...options,\n headers: {}\n };\n if (headers) {\n for (const [key, value] of Object.entries(headers)) {\n options.headers[key.toLowerCase()] = value;\n }\n }\n } else if (websocket.listenerCount('redirect') === 0) {\n const isSameHost = isIpcUrl ? websocket._originalIpc ? opts.socketPath === websocket._originalHostOrSocketPath : false : websocket._originalIpc ? false : parsedUrl.host === websocket._originalHostOrSocketPath;\n if (!isSameHost || websocket._originalSecure && !isSecure) {\n //\n // Match curl 7.77.0 behavior and drop the following headers. These\n // headers are also dropped when following a redirect to a subdomain.\n //\n delete opts.headers.authorization;\n delete opts.headers.cookie;\n if (!isSameHost) delete opts.headers.host;\n opts.auth = undefined;\n }\n }\n\n //\n // Match curl 7.77.0 behavior and make the first `Authorization` header win.\n // If the `Authorization` header is set, then there is nothing to do as it\n // will take precedence.\n //\n if (opts.auth && !options.headers.authorization) {\n options.headers.authorization = 'Basic ' + Buffer.from(opts.auth).toString('base64');\n }\n req = websocket._req = request(opts);\n if (websocket._redirects) {\n //\n // Unlike what is done for the `'upgrade'` event, no early exit is\n // triggered here if the user calls `websocket.close()` or\n // `websocket.terminate()` from a listener of the `'redirect'` event. This\n // is because the user can also call `request.destroy()` with an error\n // before calling `websocket.close()` or `websocket.terminate()` and this\n // would result in an error being emitted on the `request` object with no\n // `'error'` event listeners attached.\n //\n websocket.emit('redirect', websocket.url, req);\n }\n } else {\n req = websocket._req = request(opts);\n }\n if (opts.timeout) {\n req.on('timeout', () => {\n abortHandshake(websocket, req, 'Opening handshake has timed out');\n });\n }\n req.on('error', err => {\n if (req === null || req[kAborted]) return;\n req = websocket._req = null;\n emitErrorAndClose(websocket, err);\n });\n req.on('response', res => {\n const location = res.headers.location;\n const statusCode = res.statusCode;\n if (location && opts.followRedirects && statusCode >= 300 && statusCode < 400) {\n if (++websocket._redirects > opts.maxRedirects) {\n abortHandshake(websocket, req, 'Maximum redirects exceeded');\n return;\n }\n req.abort();\n let addr;\n try {\n addr = new URL(location, address);\n } catch (e) {\n const err = new SyntaxError(`Invalid URL: ${location}`);\n emitErrorAndClose(websocket, err);\n return;\n }\n initAsClient(websocket, addr, protocols, options);\n } else if (!websocket.emit('unexpected-response', req, res)) {\n abortHandshake(websocket, req, `Unexpected server response: ${res.statusCode}`);\n }\n });\n req.on('upgrade', (res, socket, head) => {\n websocket.emit('upgrade', res);\n\n //\n // The user may have closed the connection from a listener of the\n // `'upgrade'` event.\n //\n if (websocket.readyState !== WebSocket.CONNECTING) return;\n req = websocket._req = null;\n const upgrade = res.headers.upgrade;\n if (upgrade === undefined || upgrade.toLowerCase() !== 'websocket') {\n abortHandshake(websocket, socket, 'Invalid Upgrade header');\n return;\n }\n const digest = createHash('sha1').update(key + GUID).digest('base64');\n if (res.headers['sec-websocket-accept'] !== digest) {\n abortHandshake(websocket, socket, 'Invalid Sec-WebSocket-Accept header');\n return;\n }\n const serverProt = res.headers['sec-websocket-protocol'];\n let protError;\n if (serverProt !== undefined) {\n if (!protocolSet.size) {\n protError = 'Server sent a subprotocol but none was requested';\n } else if (!protocolSet.has(serverProt)) {\n protError = 'Server sent an invalid subprotocol';\n }\n } else if (protocolSet.size) {\n protError = 'Server sent no subprotocol';\n }\n if (protError) {\n abortHandshake(websocket, socket, protError);\n return;\n }\n if (serverProt) websocket._protocol = serverProt;\n const secWebSocketExtensions = res.headers['sec-websocket-extensions'];\n if (secWebSocketExtensions !== undefined) {\n if (!perMessageDeflate) {\n const message = 'Server sent a Sec-WebSocket-Extensions header but no extension ' + 'was requested';\n abortHandshake(websocket, socket, message);\n return;\n }\n let extensions;\n try {\n extensions = parse(secWebSocketExtensions);\n } catch (err) {\n const message = 'Invalid Sec-WebSocket-Extensions header';\n abortHandshake(websocket, socket, message);\n return;\n }\n const extensionNames = Object.keys(extensions);\n if (extensionNames.length !== 1 || extensionNames[0] !== PerMessageDeflate.extensionName) {\n const message = 'Server indicated an extension that was not requested';\n abortHandshake(websocket, socket, message);\n return;\n }\n try {\n perMessageDeflate.accept(extensions[PerMessageDeflate.extensionName]);\n } catch (err) {\n const message = 'Invalid Sec-WebSocket-Extensions header';\n abortHandshake(websocket, socket, message);\n return;\n }\n websocket._extensions[PerMessageDeflate.extensionName] = perMessageDeflate;\n }\n websocket.setSocket(socket, head, {\n allowSynchronousEvents: opts.allowSynchronousEvents,\n generateMask: opts.generateMask,\n maxPayload: opts.maxPayload,\n skipUTF8Validation: opts.skipUTF8Validation\n });\n });\n if (opts.finishRequest) {\n opts.finishRequest(req, websocket);\n } else {\n req.end();\n }\n}\n\n/**\n * Emit the `'error'` and `'close'` events.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @param {Error} The error to emit\n * @private\n */\nfunction emitErrorAndClose(websocket, err) {\n websocket._readyState = WebSocket.CLOSING;\n //\n // The following assignment is practically useless and is done only for\n // consistency.\n //\n websocket._errorEmitted = true;\n websocket.emit('error', err);\n websocket.emitClose();\n}\n\n/**\n * Create a `net.Socket` and initiate a connection.\n *\n * @param {Object} options Connection options\n * @return {net.Socket} The newly created socket used to start the connection\n * @private\n */\nfunction netConnect(options) {\n options.path = options.socketPath;\n return net.connect(options);\n}\n\n/**\n * Create a `tls.TLSSocket` and initiate a connection.\n *\n * @param {Object} options Connection options\n * @return {tls.TLSSocket} The newly created socket used to start the connection\n * @private\n */\nfunction tlsConnect(options) {\n options.path = undefined;\n if (!options.servername && options.servername !== '') {\n options.servername = net.isIP(options.host) ? '' : options.host;\n }\n return tls.connect(options);\n}\n\n/**\n * Abort the handshake and emit an error.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @param {(http.ClientRequest|net.Socket|tls.Socket)} stream The request to\n * abort or the socket to destroy\n * @param {String} message The error message\n * @private\n */\nfunction abortHandshake(websocket, stream, message) {\n websocket._readyState = WebSocket.CLOSING;\n const err = new Error(message);\n Error.captureStackTrace(err, abortHandshake);\n if (stream.setHeader) {\n stream[kAborted] = true;\n stream.abort();\n if (stream.socket && !stream.socket.destroyed) {\n //\n // On Node.js >= 14.3.0 `request.abort()` does not destroy the socket if\n // called after the request completed. See\n // https://github.com/websockets/ws/issues/1869.\n //\n stream.socket.destroy();\n }\n process.nextTick(emitErrorAndClose, websocket, err);\n } else {\n stream.destroy(err);\n stream.once('error', websocket.emit.bind(websocket, 'error'));\n stream.once('close', websocket.emitClose.bind(websocket));\n }\n}\n\n/**\n * Handle cases where the `ping()`, `pong()`, or `send()` methods are called\n * when the `readyState` attribute is `CLOSING` or `CLOSED`.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @param {*} [data] The data to send\n * @param {Function} [cb] Callback\n * @private\n */\nfunction sendAfterClose(websocket, data, cb) {\n if (data) {\n const length = isBlob(data) ? data.size : toBuffer(data).length;\n\n //\n // The `_bufferedAmount` property is used only when the peer is a client and\n // the opening handshake fails. Under these circumstances, in fact, the\n // `setSocket()` method is not called, so the `_socket` and `_sender`\n // properties are set to `null`.\n //\n if (websocket._socket) websocket._sender._bufferedBytes += length;else websocket._bufferedAmount += length;\n }\n if (cb) {\n const err = new Error(`WebSocket is not open: readyState ${websocket.readyState} ` + `(${readyStates[websocket.readyState]})`);\n process.nextTick(cb, err);\n }\n}\n\n/**\n * The listener of the `Receiver` `'conclude'` event.\n *\n * @param {Number} code The status code\n * @param {Buffer} reason The reason for closing\n * @private\n */\nfunction receiverOnConclude(code, reason) {\n const websocket = this[kWebSocket];\n websocket._closeFrameReceived = true;\n websocket._closeMessage = reason;\n websocket._closeCode = code;\n if (websocket._socket[kWebSocket] === undefined) return;\n websocket._socket.removeListener('data', socketOnData);\n process.nextTick(resume, websocket._socket);\n if (code === 1005) websocket.close();else websocket.close(code, reason);\n}\n\n/**\n * The listener of the `Receiver` `'drain'` event.\n *\n * @private\n */\nfunction receiverOnDrain() {\n const websocket = this[kWebSocket];\n if (!websocket.isPaused) websocket._socket.resume();\n}\n\n/**\n * The listener of the `Receiver` `'error'` event.\n *\n * @param {(RangeError|Error)} err The emitted error\n * @private\n */\nfunction receiverOnError(err) {\n const websocket = this[kWebSocket];\n if (websocket._socket[kWebSocket] !== undefined) {\n websocket._socket.removeListener('data', socketOnData);\n\n //\n // On Node.js < 14.0.0 the `'error'` event is emitted synchronously. See\n // https://github.com/websockets/ws/issues/1940.\n //\n process.nextTick(resume, websocket._socket);\n websocket.close(err[kStatusCode]);\n }\n if (!websocket._errorEmitted) {\n websocket._errorEmitted = true;\n websocket.emit('error', err);\n }\n}\n\n/**\n * The listener of the `Receiver` `'finish'` event.\n *\n * @private\n */\nfunction receiverOnFinish() {\n this[kWebSocket].emitClose();\n}\n\n/**\n * The listener of the `Receiver` `'message'` event.\n *\n * @param {Buffer|ArrayBuffer|Buffer[])} data The message\n * @param {Boolean} isBinary Specifies whether the message is binary or not\n * @private\n */\nfunction receiverOnMessage(data, isBinary) {\n this[kWebSocket].emit('message', data, isBinary);\n}\n\n/**\n * The listener of the `Receiver` `'ping'` event.\n *\n * @param {Buffer} data The data included in the ping frame\n * @private\n */\nfunction receiverOnPing(data) {\n const websocket = this[kWebSocket];\n if (websocket._autoPong) websocket.pong(data, !this._isServer, NOOP);\n websocket.emit('ping', data);\n}\n\n/**\n * The listener of the `Receiver` `'pong'` event.\n *\n * @param {Buffer} data The data included in the pong frame\n * @private\n */\nfunction receiverOnPong(data) {\n this[kWebSocket].emit('pong', data);\n}\n\n/**\n * Resume a readable stream\n *\n * @param {Readable} stream The readable stream\n * @private\n */\nfunction resume(stream) {\n stream.resume();\n}\n\n/**\n * The `Sender` error event handler.\n *\n * @param {Error} The error\n * @private\n */\nfunction senderOnError(err) {\n const websocket = this[kWebSocket];\n if (websocket.readyState === WebSocket.CLOSED) return;\n if (websocket.readyState === WebSocket.OPEN) {\n websocket._readyState = WebSocket.CLOSING;\n setCloseTimer(websocket);\n }\n\n //\n // `socket.end()` is used instead of `socket.destroy()` to allow the other\n // peer to finish sending queued data. There is no need to set a timer here\n // because `CLOSING` means that it is already set or not needed.\n //\n this._socket.end();\n if (!websocket._errorEmitted) {\n websocket._errorEmitted = true;\n websocket.emit('error', err);\n }\n}\n\n/**\n * Set a timer to destroy the underlying raw socket of a WebSocket.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @private\n */\nfunction setCloseTimer(websocket) {\n websocket._closeTimer = setTimeout(websocket._socket.destroy.bind(websocket._socket), closeTimeout);\n}\n\n/**\n * The listener of the socket `'close'` event.\n *\n * @private\n */\nfunction socketOnClose() {\n const websocket = this[kWebSocket];\n this.removeListener('close', socketOnClose);\n this.removeListener('data', socketOnData);\n this.removeListener('end', socketOnEnd);\n websocket._readyState = WebSocket.CLOSING;\n let chunk;\n\n //\n // The close frame might not have been received or the `'end'` event emitted,\n // for example, if the socket was destroyed due to an error. Ensure that the\n // `receiver` stream is closed after writing any remaining buffered data to\n // it. If the readable side of the socket is in flowing mode then there is no\n // buffered data as everything has been already written and `readable.read()`\n // will return `null`. If instead, the socket is paused, any possible buffered\n // data will be read as a single chunk.\n //\n if (!this._readableState.endEmitted && !websocket._closeFrameReceived && !websocket._receiver._writableState.errorEmitted && (chunk = websocket._socket.read()) !== null) {\n websocket._receiver.write(chunk);\n }\n websocket._receiver.end();\n this[kWebSocket] = undefined;\n clearTimeout(websocket._closeTimer);\n if (websocket._receiver._writableState.finished || websocket._receiver._writableState.errorEmitted) {\n websocket.emitClose();\n } else {\n websocket._receiver.on('error', receiverOnFinish);\n websocket._receiver.on('finish', receiverOnFinish);\n }\n}\n\n/**\n * The listener of the socket `'data'` event.\n *\n * @param {Buffer} chunk A chunk of data\n * @private\n */\nfunction socketOnData(chunk) {\n if (!this[kWebSocket]._receiver.write(chunk)) {\n this.pause();\n }\n}\n\n/**\n * The listener of the socket `'end'` event.\n *\n * @private\n */\nfunction socketOnEnd() {\n const websocket = this[kWebSocket];\n websocket._readyState = WebSocket.CLOSING;\n websocket._receiver.end();\n this.end();\n}\n\n/**\n * The listener of the socket `'error'` event.\n *\n * @private\n */\nfunction socketOnError() {\n const websocket = this[kWebSocket];\n this.removeListener('error', socketOnError);\n this.on('error', NOOP);\n if (websocket) {\n websocket._readyState = WebSocket.CLOSING;\n this.destroy();\n }\n}","map":{"version":3,"names":["EventEmitter","require","https","http","net","tls","randomBytes","createHash","Duplex","Readable","URL","PerMessageDeflate","Receiver","Sender","isBlob","BINARY_TYPES","EMPTY_BUFFER","GUID","kForOnEventAttribute","kListener","kStatusCode","kWebSocket","NOOP","EventTarget","addEventListener","removeEventListener","format","parse","toBuffer","closeTimeout","kAborted","Symbol","protocolVersions","readyStates","subprotocolRegex","WebSocket","constructor","address","protocols","options","_binaryType","_closeCode","_closeFrameReceived","_closeFrameSent","_closeMessage","_closeTimer","_errorEmitted","_extensions","_paused","_protocol","_readyState","CONNECTING","_receiver","_sender","_socket","_bufferedAmount","_isServer","_redirects","undefined","Array","isArray","initAsClient","_autoPong","autoPong","binaryType","type","includes","bufferedAmount","_writableState","length","_bufferedBytes","extensions","Object","keys","join","isPaused","onclose","onerror","onopen","onmessage","protocol","readyState","url","_url","setSocket","socket","head","receiver","allowSynchronousEvents","isServer","maxPayload","skipUTF8Validation","sender","generateMask","on","receiverOnConclude","receiverOnDrain","receiverOnError","receiverOnMessage","receiverOnPing","receiverOnPong","senderOnError","setTimeout","setNoDelay","unshift","socketOnClose","socketOnData","socketOnEnd","socketOnError","OPEN","emit","emitClose","CLOSED","extensionName","cleanup","removeAllListeners","close","code","data","msg","abortHandshake","_req","CLOSING","errorEmitted","end","err","setCloseTimer","pause","ping","mask","cb","Error","toString","sendAfterClose","pong","resume","needDrain","send","opts","binary","compress","fin","terminate","destroy","defineProperty","enumerable","value","indexOf","prototype","forEach","property","method","get","listener","listeners","set","handler","removeListener","module","exports","websocket","protocolVersion","perMessageDeflate","followRedirects","maxRedirects","socketPath","hostname","timeout","host","path","port","RangeError","parsedUrl","e","SyntaxError","href","isSecure","isIpcUrl","invalidUrlMessage","pathname","hash","emitErrorAndClose","defaultPort","key","request","protocolSet","Set","createConnection","tlsConnect","netConnect","startsWith","slice","headers","Connection","Upgrade","search","handshakeTimeout","offer","test","has","add","origin","Origin","username","password","auth","parts","split","req","_originalIpc","_originalSecure","_originalHostOrSocketPath","entries","toLowerCase","listenerCount","isSameHost","authorization","cookie","Buffer","from","res","location","statusCode","abort","addr","upgrade","digest","update","serverProt","protError","size","secWebSocketExtensions","message","extensionNames","accept","finishRequest","connect","servername","isIP","stream","captureStackTrace","setHeader","destroyed","process","nextTick","once","bind","reason","receiverOnFinish","isBinary","chunk","_readableState","endEmitted","read","write","clearTimeout","finished"],"sources":["/Users/shoofle/Projects/the-forest/node_modules/@libsql/isomorphic-ws/node_modules/ws/lib/websocket.js"],"sourcesContent":["/* eslint no-unused-vars: [\"error\", { \"varsIgnorePattern\": \"^Duplex|Readable$\", \"caughtErrors\": \"none\" }] */\n\n'use strict';\n\nconst EventEmitter = require('events');\nconst https = require('https');\nconst http = require('http');\nconst net = require('net');\nconst tls = require('tls');\nconst { randomBytes, createHash } = require('crypto');\nconst { Duplex, Readable } = require('stream');\nconst { URL } = require('url');\n\nconst PerMessageDeflate = require('./permessage-deflate');\nconst Receiver = require('./receiver');\nconst Sender = require('./sender');\nconst { isBlob } = require('./validation');\n\nconst {\n BINARY_TYPES,\n EMPTY_BUFFER,\n GUID,\n kForOnEventAttribute,\n kListener,\n kStatusCode,\n kWebSocket,\n NOOP\n} = require('./constants');\nconst {\n EventTarget: { addEventListener, removeEventListener }\n} = require('./event-target');\nconst { format, parse } = require('./extension');\nconst { toBuffer } = require('./buffer-util');\n\nconst closeTimeout = 30 * 1000;\nconst kAborted = Symbol('kAborted');\nconst protocolVersions = [8, 13];\nconst readyStates = ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED'];\nconst subprotocolRegex = /^[!#$%&'*+\\-.0-9A-Z^_`|a-z~]+$/;\n\n/**\n * Class representing a WebSocket.\n *\n * @extends EventEmitter\n */\nclass WebSocket extends EventEmitter {\n /**\n * Create a new `WebSocket`.\n *\n * @param {(String|URL)} address The URL to which to connect\n * @param {(String|String[])} [protocols] The subprotocols\n * @param {Object} [options] Connection options\n */\n constructor(address, protocols, options) {\n super();\n\n this._binaryType = BINARY_TYPES[0];\n this._closeCode = 1006;\n this._closeFrameReceived = false;\n this._closeFrameSent = false;\n this._closeMessage = EMPTY_BUFFER;\n this._closeTimer = null;\n this._errorEmitted = false;\n this._extensions = {};\n this._paused = false;\n this._protocol = '';\n this._readyState = WebSocket.CONNECTING;\n this._receiver = null;\n this._sender = null;\n this._socket = null;\n\n if (address !== null) {\n this._bufferedAmount = 0;\n this._isServer = false;\n this._redirects = 0;\n\n if (protocols === undefined) {\n protocols = [];\n } else if (!Array.isArray(protocols)) {\n if (typeof protocols === 'object' && protocols !== null) {\n options = protocols;\n protocols = [];\n } else {\n protocols = [protocols];\n }\n }\n\n initAsClient(this, address, protocols, options);\n } else {\n this._autoPong = options.autoPong;\n this._isServer = true;\n }\n }\n\n /**\n * For historical reasons, the custom \"nodebuffer\" type is used by the default\n * instead of \"blob\".\n *\n * @type {String}\n */\n get binaryType() {\n return this._binaryType;\n }\n\n set binaryType(type) {\n if (!BINARY_TYPES.includes(type)) return;\n\n this._binaryType = type;\n\n //\n // Allow to change `binaryType` on the fly.\n //\n if (this._receiver) this._receiver._binaryType = type;\n }\n\n /**\n * @type {Number}\n */\n get bufferedAmount() {\n if (!this._socket) return this._bufferedAmount;\n\n return this._socket._writableState.length + this._sender._bufferedBytes;\n }\n\n /**\n * @type {String}\n */\n get extensions() {\n return Object.keys(this._extensions).join();\n }\n\n /**\n * @type {Boolean}\n */\n get isPaused() {\n return this._paused;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onclose() {\n return null;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onerror() {\n return null;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onopen() {\n return null;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onmessage() {\n return null;\n }\n\n /**\n * @type {String}\n */\n get protocol() {\n return this._protocol;\n }\n\n /**\n * @type {Number}\n */\n get readyState() {\n return this._readyState;\n }\n\n /**\n * @type {String}\n */\n get url() {\n return this._url;\n }\n\n /**\n * Set up the socket and the internal resources.\n *\n * @param {Duplex} socket The network socket between the server and client\n * @param {Buffer} head The first packet of the upgraded stream\n * @param {Object} options Options object\n * @param {Boolean} [options.allowSynchronousEvents=false] Specifies whether\n * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted\n * multiple times in the same tick\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Number} [options.maxPayload=0] The maximum allowed message size\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n * @private\n */\n setSocket(socket, head, options) {\n const receiver = new Receiver({\n allowSynchronousEvents: options.allowSynchronousEvents,\n binaryType: this.binaryType,\n extensions: this._extensions,\n isServer: this._isServer,\n maxPayload: options.maxPayload,\n skipUTF8Validation: options.skipUTF8Validation\n });\n\n const sender = new Sender(socket, this._extensions, options.generateMask);\n\n this._receiver = receiver;\n this._sender = sender;\n this._socket = socket;\n\n receiver[kWebSocket] = this;\n sender[kWebSocket] = this;\n socket[kWebSocket] = this;\n\n receiver.on('conclude', receiverOnConclude);\n receiver.on('drain', receiverOnDrain);\n receiver.on('error', receiverOnError);\n receiver.on('message', receiverOnMessage);\n receiver.on('ping', receiverOnPing);\n receiver.on('pong', receiverOnPong);\n\n sender.onerror = senderOnError;\n\n //\n // These methods may not be available if `socket` is just a `Duplex`.\n //\n if (socket.setTimeout) socket.setTimeout(0);\n if (socket.setNoDelay) socket.setNoDelay();\n\n if (head.length > 0) socket.unshift(head);\n\n socket.on('close', socketOnClose);\n socket.on('data', socketOnData);\n socket.on('end', socketOnEnd);\n socket.on('error', socketOnError);\n\n this._readyState = WebSocket.OPEN;\n this.emit('open');\n }\n\n /**\n * Emit the `'close'` event.\n *\n * @private\n */\n emitClose() {\n if (!this._socket) {\n this._readyState = WebSocket.CLOSED;\n this.emit('close', this._closeCode, this._closeMessage);\n return;\n }\n\n if (this._extensions[PerMessageDeflate.extensionName]) {\n this._extensions[PerMessageDeflate.extensionName].cleanup();\n }\n\n this._receiver.removeAllListeners();\n this._readyState = WebSocket.CLOSED;\n this.emit('close', this._closeCode, this._closeMessage);\n }\n\n /**\n * Start a closing handshake.\n *\n * +----------+ +-----------+ +----------+\n * - - -|ws.close()|-->|close frame|-->|ws.close()|- - -\n * | +----------+ +-----------+ +----------+ |\n * +----------+ +-----------+ |\n * CLOSING |ws.close()|<--|close frame|<--+-----+ CLOSING\n * +----------+ +-----------+ |\n * | | | +---+ |\n * +------------------------+-->|fin| - - - -\n * | +---+ | +---+\n * - - - - -|fin|<---------------------+\n * +---+\n *\n * @param {Number} [code] Status code explaining why the connection is closing\n * @param {(String|Buffer)} [data] The reason why the connection is\n * closing\n * @public\n */\n close(code, data) {\n if (this.readyState === WebSocket.CLOSED) return;\n if (this.readyState === WebSocket.CONNECTING) {\n const msg = 'WebSocket was closed before the connection was established';\n abortHandshake(this, this._req, msg);\n return;\n }\n\n if (this.readyState === WebSocket.CLOSING) {\n if (\n this._closeFrameSent &&\n (this._closeFrameReceived || this._receiver._writableState.errorEmitted)\n ) {\n this._socket.end();\n }\n\n return;\n }\n\n this._readyState = WebSocket.CLOSING;\n this._sender.close(code, data, !this._isServer, (err) => {\n //\n // This error is handled by the `'error'` listener on the socket. We only\n // want to know if the close frame has been sent here.\n //\n if (err) return;\n\n this._closeFrameSent = true;\n\n if (\n this._closeFrameReceived ||\n this._receiver._writableState.errorEmitted\n ) {\n this._socket.end();\n }\n });\n\n setCloseTimer(this);\n }\n\n /**\n * Pause the socket.\n *\n * @public\n */\n pause() {\n if (\n this.readyState === WebSocket.CONNECTING ||\n this.readyState === WebSocket.CLOSED\n ) {\n return;\n }\n\n this._paused = true;\n this._socket.pause();\n }\n\n /**\n * Send a ping.\n *\n * @param {*} [data] The data to send\n * @param {Boolean} [mask] Indicates whether or not to mask `data`\n * @param {Function} [cb] Callback which is executed when the ping is sent\n * @public\n */\n ping(data, mask, cb) {\n if (this.readyState === WebSocket.CONNECTING) {\n throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');\n }\n\n if (typeof data === 'function') {\n cb = data;\n data = mask = undefined;\n } else if (typeof mask === 'function') {\n cb = mask;\n mask = undefined;\n }\n\n if (typeof data === 'number') data = data.toString();\n\n if (this.readyState !== WebSocket.OPEN) {\n sendAfterClose(this, data, cb);\n return;\n }\n\n if (mask === undefined) mask = !this._isServer;\n this._sender.ping(data || EMPTY_BUFFER, mask, cb);\n }\n\n /**\n * Send a pong.\n *\n * @param {*} [data] The data to send\n * @param {Boolean} [mask] Indicates whether or not to mask `data`\n * @param {Function} [cb] Callback which is executed when the pong is sent\n * @public\n */\n pong(data, mask, cb) {\n if (this.readyState === WebSocket.CONNECTING) {\n throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');\n }\n\n if (typeof data === 'function') {\n cb = data;\n data = mask = undefined;\n } else if (typeof mask === 'function') {\n cb = mask;\n mask = undefined;\n }\n\n if (typeof data === 'number') data = data.toString();\n\n if (this.readyState !== WebSocket.OPEN) {\n sendAfterClose(this, data, cb);\n return;\n }\n\n if (mask === undefined) mask = !this._isServer;\n this._sender.pong(data || EMPTY_BUFFER, mask, cb);\n }\n\n /**\n * Resume the socket.\n *\n * @public\n */\n resume() {\n if (\n this.readyState === WebSocket.CONNECTING ||\n this.readyState === WebSocket.CLOSED\n ) {\n return;\n }\n\n this._paused = false;\n if (!this._receiver._writableState.needDrain) this._socket.resume();\n }\n\n /**\n * Send a data message.\n *\n * @param {*} data The message to send\n * @param {Object} [options] Options object\n * @param {Boolean} [options.binary] Specifies whether `data` is binary or\n * text\n * @param {Boolean} [options.compress] Specifies whether or not to compress\n * `data`\n * @param {Boolean} [options.fin=true] Specifies whether the fragment is the\n * last one\n * @param {Boolean} [options.mask] Specifies whether or not to mask `data`\n * @param {Function} [cb] Callback which is executed when data is written out\n * @public\n */\n send(data, options, cb) {\n if (this.readyState === WebSocket.CONNECTING) {\n throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');\n }\n\n if (typeof options === 'function') {\n cb = options;\n options = {};\n }\n\n if (typeof data === 'number') data = data.toString();\n\n if (this.readyState !== WebSocket.OPEN) {\n sendAfterClose(this, data, cb);\n return;\n }\n\n const opts = {\n binary: typeof data !== 'string',\n mask: !this._isServer,\n compress: true,\n fin: true,\n ...options\n };\n\n if (!this._extensions[PerMessageDeflate.extensionName]) {\n opts.compress = false;\n }\n\n this._sender.send(data || EMPTY_BUFFER, opts, cb);\n }\n\n /**\n * Forcibly close the connection.\n *\n * @public\n */\n terminate() {\n if (this.readyState === WebSocket.CLOSED) return;\n if (this.readyState === WebSocket.CONNECTING) {\n const msg = 'WebSocket was closed before the connection was established';\n abortHandshake(this, this._req, msg);\n return;\n }\n\n if (this._socket) {\n this._readyState = WebSocket.CLOSING;\n this._socket.destroy();\n }\n }\n}\n\n/**\n * @constant {Number} CONNECTING\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'CONNECTING', {\n enumerable: true,\n value: readyStates.indexOf('CONNECTING')\n});\n\n/**\n * @constant {Number} CONNECTING\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'CONNECTING', {\n enumerable: true,\n value: readyStates.indexOf('CONNECTING')\n});\n\n/**\n * @constant {Number} OPEN\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'OPEN', {\n enumerable: true,\n value: readyStates.indexOf('OPEN')\n});\n\n/**\n * @constant {Number} OPEN\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'OPEN', {\n enumerable: true,\n value: readyStates.indexOf('OPEN')\n});\n\n/**\n * @constant {Number} CLOSING\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'CLOSING', {\n enumerable: true,\n value: readyStates.indexOf('CLOSING')\n});\n\n/**\n * @constant {Number} CLOSING\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'CLOSING', {\n enumerable: true,\n value: readyStates.indexOf('CLOSING')\n});\n\n/**\n * @constant {Number} CLOSED\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'CLOSED', {\n enumerable: true,\n value: readyStates.indexOf('CLOSED')\n});\n\n/**\n * @constant {Number} CLOSED\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'CLOSED', {\n enumerable: true,\n value: readyStates.indexOf('CLOSED')\n});\n\n[\n 'binaryType',\n 'bufferedAmount',\n 'extensions',\n 'isPaused',\n 'protocol',\n 'readyState',\n 'url'\n].forEach((property) => {\n Object.defineProperty(WebSocket.prototype, property, { enumerable: true });\n});\n\n//\n// Add the `onopen`, `onerror`, `onclose`, and `onmessage` attributes.\n// See https://html.spec.whatwg.org/multipage/comms.html#the-websocket-interface\n//\n['open', 'error', 'close', 'message'].forEach((method) => {\n Object.defineProperty(WebSocket.prototype, `on${method}`, {\n enumerable: true,\n get() {\n for (const listener of this.listeners(method)) {\n if (listener[kForOnEventAttribute]) return listener[kListener];\n }\n\n return null;\n },\n set(handler) {\n for (const listener of this.listeners(method)) {\n if (listener[kForOnEventAttribute]) {\n this.removeListener(method, listener);\n break;\n }\n }\n\n if (typeof handler !== 'function') return;\n\n this.addEventListener(method, handler, {\n [kForOnEventAttribute]: true\n });\n }\n });\n});\n\nWebSocket.prototype.addEventListener = addEventListener;\nWebSocket.prototype.removeEventListener = removeEventListener;\n\nmodule.exports = WebSocket;\n\n/**\n * Initialize a WebSocket client.\n *\n * @param {WebSocket} websocket The client to initialize\n * @param {(String|URL)} address The URL to which to connect\n * @param {Array} protocols The subprotocols\n * @param {Object} [options] Connection options\n * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether any\n * of the `'message'`, `'ping'`, and `'pong'` events can be emitted multiple\n * times in the same tick\n * @param {Boolean} [options.autoPong=true] Specifies whether or not to\n * automatically send a pong in response to a ping\n * @param {Function} [options.finishRequest] A function which can be used to\n * customize the headers of each http request before it is sent\n * @param {Boolean} [options.followRedirects=false] Whether or not to follow\n * redirects\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Number} [options.handshakeTimeout] Timeout in milliseconds for the\n * handshake request\n * @param {Number} [options.maxPayload=104857600] The maximum allowed message\n * size\n * @param {Number} [options.maxRedirects=10] The maximum number of redirects\n * allowed\n * @param {String} [options.origin] Value of the `Origin` or\n * `Sec-WebSocket-Origin` header\n * @param {(Boolean|Object)} [options.perMessageDeflate=true] Enable/disable\n * permessage-deflate\n * @param {Number} [options.protocolVersion=13] Value of the\n * `Sec-WebSocket-Version` header\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n * @private\n */\nfunction initAsClient(websocket, address, protocols, options) {\n const opts = {\n allowSynchronousEvents: true,\n autoPong: true,\n protocolVersion: protocolVersions[1],\n maxPayload: 100 * 1024 * 1024,\n skipUTF8Validation: false,\n perMessageDeflate: true,\n followRedirects: false,\n maxRedirects: 10,\n ...options,\n socketPath: undefined,\n hostname: undefined,\n protocol: undefined,\n timeout: undefined,\n method: 'GET',\n host: undefined,\n path: undefined,\n port: undefined\n };\n\n websocket._autoPong = opts.autoPong;\n\n if (!protocolVersions.includes(opts.protocolVersion)) {\n throw new RangeError(\n `Unsupported protocol version: ${opts.protocolVersion} ` +\n `(supported versions: ${protocolVersions.join(', ')})`\n );\n }\n\n let parsedUrl;\n\n if (address instanceof URL) {\n parsedUrl = address;\n } else {\n try {\n parsedUrl = new URL(address);\n } catch (e) {\n throw new SyntaxError(`Invalid URL: ${address}`);\n }\n }\n\n if (parsedUrl.protocol === 'http:') {\n parsedUrl.protocol = 'ws:';\n } else if (parsedUrl.protocol === 'https:') {\n parsedUrl.protocol = 'wss:';\n }\n\n websocket._url = parsedUrl.href;\n\n const isSecure = parsedUrl.protocol === 'wss:';\n const isIpcUrl = parsedUrl.protocol === 'ws+unix:';\n let invalidUrlMessage;\n\n if (parsedUrl.protocol !== 'ws:' && !isSecure && !isIpcUrl) {\n invalidUrlMessage =\n 'The URL\\'s protocol must be one of \"ws:\", \"wss:\", ' +\n '\"http:\", \"https\", or \"ws+unix:\"';\n } else if (isIpcUrl && !parsedUrl.pathname) {\n invalidUrlMessage = \"The URL's pathname is empty\";\n } else if (parsedUrl.hash) {\n invalidUrlMessage = 'The URL contains a fragment identifier';\n }\n\n if (invalidUrlMessage) {\n const err = new SyntaxError(invalidUrlMessage);\n\n if (websocket._redirects === 0) {\n throw err;\n } else {\n emitErrorAndClose(websocket, err);\n return;\n }\n }\n\n const defaultPort = isSecure ? 443 : 80;\n const key = randomBytes(16).toString('base64');\n const request = isSecure ? https.request : http.request;\n const protocolSet = new Set();\n let perMessageDeflate;\n\n opts.createConnection =\n opts.createConnection || (isSecure ? tlsConnect : netConnect);\n opts.defaultPort = opts.defaultPort || defaultPort;\n opts.port = parsedUrl.port || defaultPort;\n opts.host = parsedUrl.hostname.startsWith('[')\n ? parsedUrl.hostname.slice(1, -1)\n : parsedUrl.hostname;\n opts.headers = {\n ...opts.headers,\n 'Sec-WebSocket-Version': opts.protocolVersion,\n 'Sec-WebSocket-Key': key,\n Connection: 'Upgrade',\n Upgrade: 'websocket'\n };\n opts.path = parsedUrl.pathname + parsedUrl.search;\n opts.timeout = opts.handshakeTimeout;\n\n if (opts.perMessageDeflate) {\n perMessageDeflate = new PerMessageDeflate(\n opts.perMessageDeflate !== true ? opts.perMessageDeflate : {},\n false,\n opts.maxPayload\n );\n opts.headers['Sec-WebSocket-Extensions'] = format({\n [PerMessageDeflate.extensionName]: perMessageDeflate.offer()\n });\n }\n if (protocols.length) {\n for (const protocol of protocols) {\n if (\n typeof protocol !== 'string' ||\n !subprotocolRegex.test(protocol) ||\n protocolSet.has(protocol)\n ) {\n throw new SyntaxError(\n 'An invalid or duplicated subprotocol was specified'\n );\n }\n\n protocolSet.add(protocol);\n }\n\n opts.headers['Sec-WebSocket-Protocol'] = protocols.join(',');\n }\n if (opts.origin) {\n if (opts.protocolVersion < 13) {\n opts.headers['Sec-WebSocket-Origin'] = opts.origin;\n } else {\n opts.headers.Origin = opts.origin;\n }\n }\n if (parsedUrl.username || parsedUrl.password) {\n opts.auth = `${parsedUrl.username}:${parsedUrl.password}`;\n }\n\n if (isIpcUrl) {\n const parts = opts.path.split(':');\n\n opts.socketPath = parts[0];\n opts.path = parts[1];\n }\n\n let req;\n\n if (opts.followRedirects) {\n if (websocket._redirects === 0) {\n websocket._originalIpc = isIpcUrl;\n websocket._originalSecure = isSecure;\n websocket._originalHostOrSocketPath = isIpcUrl\n ? opts.socketPath\n : parsedUrl.host;\n\n const headers = options && options.headers;\n\n //\n // Shallow copy the user provided options so that headers can be changed\n // without mutating the original object.\n //\n options = { ...options, headers: {} };\n\n if (headers) {\n for (const [key, value] of Object.entries(headers)) {\n options.headers[key.toLowerCase()] = value;\n }\n }\n } else if (websocket.listenerCount('redirect') === 0) {\n const isSameHost = isIpcUrl\n ? websocket._originalIpc\n ? opts.socketPath === websocket._originalHostOrSocketPath\n : false\n : websocket._originalIpc\n ? false\n : parsedUrl.host === websocket._originalHostOrSocketPath;\n\n if (!isSameHost || (websocket._originalSecure && !isSecure)) {\n //\n // Match curl 7.77.0 behavior and drop the following headers. These\n // headers are also dropped when following a redirect to a subdomain.\n //\n delete opts.headers.authorization;\n delete opts.headers.cookie;\n\n if (!isSameHost) delete opts.headers.host;\n\n opts.auth = undefined;\n }\n }\n\n //\n // Match curl 7.77.0 behavior and make the first `Authorization` header win.\n // If the `Authorization` header is set, then there is nothing to do as it\n // will take precedence.\n //\n if (opts.auth && !options.headers.authorization) {\n options.headers.authorization =\n 'Basic ' + Buffer.from(opts.auth).toString('base64');\n }\n\n req = websocket._req = request(opts);\n\n if (websocket._redirects) {\n //\n // Unlike what is done for the `'upgrade'` event, no early exit is\n // triggered here if the user calls `websocket.close()` or\n // `websocket.terminate()` from a listener of the `'redirect'` event. This\n // is because the user can also call `request.destroy()` with an error\n // before calling `websocket.close()` or `websocket.terminate()` and this\n // would result in an error being emitted on the `request` object with no\n // `'error'` event listeners attached.\n //\n websocket.emit('redirect', websocket.url, req);\n }\n } else {\n req = websocket._req = request(opts);\n }\n\n if (opts.timeout) {\n req.on('timeout', () => {\n abortHandshake(websocket, req, 'Opening handshake has timed out');\n });\n }\n\n req.on('error', (err) => {\n if (req === null || req[kAborted]) return;\n\n req = websocket._req = null;\n emitErrorAndClose(websocket, err);\n });\n\n req.on('response', (res) => {\n const location = res.headers.location;\n const statusCode = res.statusCode;\n\n if (\n location &&\n opts.followRedirects &&\n statusCode >= 300 &&\n statusCode < 400\n ) {\n if (++websocket._redirects > opts.maxRedirects) {\n abortHandshake(websocket, req, 'Maximum redirects exceeded');\n return;\n }\n\n req.abort();\n\n let addr;\n\n try {\n addr = new URL(location, address);\n } catch (e) {\n const err = new SyntaxError(`Invalid URL: ${location}`);\n emitErrorAndClose(websocket, err);\n return;\n }\n\n initAsClient(websocket, addr, protocols, options);\n } else if (!websocket.emit('unexpected-response', req, res)) {\n abortHandshake(\n websocket,\n req,\n `Unexpected server response: ${res.statusCode}`\n );\n }\n });\n\n req.on('upgrade', (res, socket, head) => {\n websocket.emit('upgrade', res);\n\n //\n // The user may have closed the connection from a listener of the\n // `'upgrade'` event.\n //\n if (websocket.readyState !== WebSocket.CONNECTING) return;\n\n req = websocket._req = null;\n\n const upgrade = res.headers.upgrade;\n\n if (upgrade === undefined || upgrade.toLowerCase() !== 'websocket') {\n abortHandshake(websocket, socket, 'Invalid Upgrade header');\n return;\n }\n\n const digest = createHash('sha1')\n .update(key + GUID)\n .digest('base64');\n\n if (res.headers['sec-websocket-accept'] !== digest) {\n abortHandshake(websocket, socket, 'Invalid Sec-WebSocket-Accept header');\n return;\n }\n\n const serverProt = res.headers['sec-websocket-protocol'];\n let protError;\n\n if (serverProt !== undefined) {\n if (!protocolSet.size) {\n protError = 'Server sent a subprotocol but none was requested';\n } else if (!protocolSet.has(serverProt)) {\n protError = 'Server sent an invalid subprotocol';\n }\n } else if (protocolSet.size) {\n protError = 'Server sent no subprotocol';\n }\n\n if (protError) {\n abortHandshake(websocket, socket, protError);\n return;\n }\n\n if (serverProt) websocket._protocol = serverProt;\n\n const secWebSocketExtensions = res.headers['sec-websocket-extensions'];\n\n if (secWebSocketExtensions !== undefined) {\n if (!perMessageDeflate) {\n const message =\n 'Server sent a Sec-WebSocket-Extensions header but no extension ' +\n 'was requested';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n let extensions;\n\n try {\n extensions = parse(secWebSocketExtensions);\n } catch (err) {\n const message = 'Invalid Sec-WebSocket-Extensions header';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n const extensionNames = Object.keys(extensions);\n\n if (\n extensionNames.length !== 1 ||\n extensionNames[0] !== PerMessageDeflate.extensionName\n ) {\n const message = 'Server indicated an extension that was not requested';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n try {\n perMessageDeflate.accept(extensions[PerMessageDeflate.extensionName]);\n } catch (err) {\n const message = 'Invalid Sec-WebSocket-Extensions header';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n websocket._extensions[PerMessageDeflate.extensionName] =\n perMessageDeflate;\n }\n\n websocket.setSocket(socket, head, {\n allowSynchronousEvents: opts.allowSynchronousEvents,\n generateMask: opts.generateMask,\n maxPayload: opts.maxPayload,\n skipUTF8Validation: opts.skipUTF8Validation\n });\n });\n\n if (opts.finishRequest) {\n opts.finishRequest(req, websocket);\n } else {\n req.end();\n }\n}\n\n/**\n * Emit the `'error'` and `'close'` events.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @param {Error} The error to emit\n * @private\n */\nfunction emitErrorAndClose(websocket, err) {\n websocket._readyState = WebSocket.CLOSING;\n //\n // The following assignment is practically useless and is done only for\n // consistency.\n //\n websocket._errorEmitted = true;\n websocket.emit('error', err);\n websocket.emitClose();\n}\n\n/**\n * Create a `net.Socket` and initiate a connection.\n *\n * @param {Object} options Connection options\n * @return {net.Socket} The newly created socket used to start the connection\n * @private\n */\nfunction netConnect(options) {\n options.path = options.socketPath;\n return net.connect(options);\n}\n\n/**\n * Create a `tls.TLSSocket` and initiate a connection.\n *\n * @param {Object} options Connection options\n * @return {tls.TLSSocket} The newly created socket used to start the connection\n * @private\n */\nfunction tlsConnect(options) {\n options.path = undefined;\n\n if (!options.servername && options.servername !== '') {\n options.servername = net.isIP(options.host) ? '' : options.host;\n }\n\n return tls.connect(options);\n}\n\n/**\n * Abort the handshake and emit an error.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @param {(http.ClientRequest|net.Socket|tls.Socket)} stream The request to\n * abort or the socket to destroy\n * @param {String} message The error message\n * @private\n */\nfunction abortHandshake(websocket, stream, message) {\n websocket._readyState = WebSocket.CLOSING;\n\n const err = new Error(message);\n Error.captureStackTrace(err, abortHandshake);\n\n if (stream.setHeader) {\n stream[kAborted] = true;\n stream.abort();\n\n if (stream.socket && !stream.socket.destroyed) {\n //\n // On Node.js >= 14.3.0 `request.abort()` does not destroy the socket if\n // called after the request completed. See\n // https://github.com/websockets/ws/issues/1869.\n //\n stream.socket.destroy();\n }\n\n process.nextTick(emitErrorAndClose, websocket, err);\n } else {\n stream.destroy(err);\n stream.once('error', websocket.emit.bind(websocket, 'error'));\n stream.once('close', websocket.emitClose.bind(websocket));\n }\n}\n\n/**\n * Handle cases where the `ping()`, `pong()`, or `send()` methods are called\n * when the `readyState` attribute is `CLOSING` or `CLOSED`.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @param {*} [data] The data to send\n * @param {Function} [cb] Callback\n * @private\n */\nfunction sendAfterClose(websocket, data, cb) {\n if (data) {\n const length = isBlob(data) ? data.size : toBuffer(data).length;\n\n //\n // The `_bufferedAmount` property is used only when the peer is a client and\n // the opening handshake fails. Under these circumstances, in fact, the\n // `setSocket()` method is not called, so the `_socket` and `_sender`\n // properties are set to `null`.\n //\n if (websocket._socket) websocket._sender._bufferedBytes += length;\n else websocket._bufferedAmount += length;\n }\n\n if (cb) {\n const err = new Error(\n `WebSocket is not open: readyState ${websocket.readyState} ` +\n `(${readyStates[websocket.readyState]})`\n );\n process.nextTick(cb, err);\n }\n}\n\n/**\n * The listener of the `Receiver` `'conclude'` event.\n *\n * @param {Number} code The status code\n * @param {Buffer} reason The reason for closing\n * @private\n */\nfunction receiverOnConclude(code, reason) {\n const websocket = this[kWebSocket];\n\n websocket._closeFrameReceived = true;\n websocket._closeMessage = reason;\n websocket._closeCode = code;\n\n if (websocket._socket[kWebSocket] === undefined) return;\n\n websocket._socket.removeListener('data', socketOnData);\n process.nextTick(resume, websocket._socket);\n\n if (code === 1005) websocket.close();\n else websocket.close(code, reason);\n}\n\n/**\n * The listener of the `Receiver` `'drain'` event.\n *\n * @private\n */\nfunction receiverOnDrain() {\n const websocket = this[kWebSocket];\n\n if (!websocket.isPaused) websocket._socket.resume();\n}\n\n/**\n * The listener of the `Receiver` `'error'` event.\n *\n * @param {(RangeError|Error)} err The emitted error\n * @private\n */\nfunction receiverOnError(err) {\n const websocket = this[kWebSocket];\n\n if (websocket._socket[kWebSocket] !== undefined) {\n websocket._socket.removeListener('data', socketOnData);\n\n //\n // On Node.js < 14.0.0 the `'error'` event is emitted synchronously. See\n // https://github.com/websockets/ws/issues/1940.\n //\n process.nextTick(resume, websocket._socket);\n\n websocket.close(err[kStatusCode]);\n }\n\n if (!websocket._errorEmitted) {\n websocket._errorEmitted = true;\n websocket.emit('error', err);\n }\n}\n\n/**\n * The listener of the `Receiver` `'finish'` event.\n *\n * @private\n */\nfunction receiverOnFinish() {\n this[kWebSocket].emitClose();\n}\n\n/**\n * The listener of the `Receiver` `'message'` event.\n *\n * @param {Buffer|ArrayBuffer|Buffer[])} data The message\n * @param {Boolean} isBinary Specifies whether the message is binary or not\n * @private\n */\nfunction receiverOnMessage(data, isBinary) {\n this[kWebSocket].emit('message', data, isBinary);\n}\n\n/**\n * The listener of the `Receiver` `'ping'` event.\n *\n * @param {Buffer} data The data included in the ping frame\n * @private\n */\nfunction receiverOnPing(data) {\n const websocket = this[kWebSocket];\n\n if (websocket._autoPong) websocket.pong(data, !this._isServer, NOOP);\n websocket.emit('ping', data);\n}\n\n/**\n * The listener of the `Receiver` `'pong'` event.\n *\n * @param {Buffer} data The data included in the pong frame\n * @private\n */\nfunction receiverOnPong(data) {\n this[kWebSocket].emit('pong', data);\n}\n\n/**\n * Resume a readable stream\n *\n * @param {Readable} stream The readable stream\n * @private\n */\nfunction resume(stream) {\n stream.resume();\n}\n\n/**\n * The `Sender` error event handler.\n *\n * @param {Error} The error\n * @private\n */\nfunction senderOnError(err) {\n const websocket = this[kWebSocket];\n\n if (websocket.readyState === WebSocket.CLOSED) return;\n if (websocket.readyState === WebSocket.OPEN) {\n websocket._readyState = WebSocket.CLOSING;\n setCloseTimer(websocket);\n }\n\n //\n // `socket.end()` is used instead of `socket.destroy()` to allow the other\n // peer to finish sending queued data. There is no need to set a timer here\n // because `CLOSING` means that it is already set or not needed.\n //\n this._socket.end();\n\n if (!websocket._errorEmitted) {\n websocket._errorEmitted = true;\n websocket.emit('error', err);\n }\n}\n\n/**\n * Set a timer to destroy the underlying raw socket of a WebSocket.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @private\n */\nfunction setCloseTimer(websocket) {\n websocket._closeTimer = setTimeout(\n websocket._socket.destroy.bind(websocket._socket),\n closeTimeout\n );\n}\n\n/**\n * The listener of the socket `'close'` event.\n *\n * @private\n */\nfunction socketOnClose() {\n const websocket = this[kWebSocket];\n\n this.removeListener('close', socketOnClose);\n this.removeListener('data', socketOnData);\n this.removeListener('end', socketOnEnd);\n\n websocket._readyState = WebSocket.CLOSING;\n\n let chunk;\n\n //\n // The close frame might not have been received or the `'end'` event emitted,\n // for example, if the socket was destroyed due to an error. Ensure that the\n // `receiver` stream is closed after writing any remaining buffered data to\n // it. If the readable side of the socket is in flowing mode then there is no\n // buffered data as everything has been already written and `readable.read()`\n // will return `null`. If instead, the socket is paused, any possible buffered\n // data will be read as a single chunk.\n //\n if (\n !this._readableState.endEmitted &&\n !websocket._closeFrameReceived &&\n !websocket._receiver._writableState.errorEmitted &&\n (chunk = websocket._socket.read()) !== null\n ) {\n websocket._receiver.write(chunk);\n }\n\n websocket._receiver.end();\n\n this[kWebSocket] = undefined;\n\n clearTimeout(websocket._closeTimer);\n\n if (\n websocket._receiver._writableState.finished ||\n websocket._receiver._writableState.errorEmitted\n ) {\n websocket.emitClose();\n } else {\n websocket._receiver.on('error', receiverOnFinish);\n websocket._receiver.on('finish', receiverOnFinish);\n }\n}\n\n/**\n * The listener of the socket `'data'` event.\n *\n * @param {Buffer} chunk A chunk of data\n * @private\n */\nfunction socketOnData(chunk) {\n if (!this[kWebSocket]._receiver.write(chunk)) {\n this.pause();\n }\n}\n\n/**\n * The listener of the socket `'end'` event.\n *\n * @private\n */\nfunction socketOnEnd() {\n const websocket = this[kWebSocket];\n\n websocket._readyState = WebSocket.CLOSING;\n websocket._receiver.end();\n this.end();\n}\n\n/**\n * The listener of the socket `'error'` event.\n *\n * @private\n */\nfunction socketOnError() {\n const websocket = this[kWebSocket];\n\n this.removeListener('error', socketOnError);\n this.on('error', NOOP);\n\n if (websocket) {\n websocket._readyState = WebSocket.CLOSING;\n this.destroy();\n }\n}\n"],"mappings":"AAAA;;AAEA,YAAY;;AAEZ,MAAMA,YAAY,GAAGC,OAAO,CAAC,QAAQ,CAAC;AACtC,MAAMC,KAAK,GAAGD,OAAO,CAAC,OAAO,CAAC;AAC9B,MAAME,IAAI,GAAGF,OAAO,CAAC,MAAM,CAAC;AAC5B,MAAMG,GAAG,GAAGH,OAAO,CAAC,KAAK,CAAC;AAC1B,MAAMI,GAAG,GAAGJ,OAAO,CAAC,KAAK,CAAC;AAC1B,MAAM;EAAEK,WAAW;EAAEC;AAAW,CAAC,GAAGN,OAAO,CAAC,QAAQ,CAAC;AACrD,MAAM;EAAEO,MAAM;EAAEC;AAAS,CAAC,GAAGR,OAAO,CAAC,QAAQ,CAAC;AAC9C,MAAM;EAAES;AAAI,CAAC,GAAGT,OAAO,CAAC,KAAK,CAAC;AAE9B,MAAMU,iBAAiB,GAAGV,OAAO,CAAC,sBAAsB,CAAC;AACzD,MAAMW,QAAQ,GAAGX,OAAO,CAAC,YAAY,CAAC;AACtC,MAAMY,MAAM,GAAGZ,OAAO,CAAC,UAAU,CAAC;AAClC,MAAM;EAAEa;AAAO,CAAC,GAAGb,OAAO,CAAC,cAAc,CAAC;AAE1C,MAAM;EACJc,YAAY;EACZC,YAAY;EACZC,IAAI;EACJC,oBAAoB;EACpBC,SAAS;EACTC,WAAW;EACXC,UAAU;EACVC;AACF,CAAC,GAAGrB,OAAO,CAAC,aAAa,CAAC;AAC1B,MAAM;EACJsB,WAAW,EAAE;IAAEC,gBAAgB;IAAEC;EAAoB;AACvD,CAAC,GAAGxB,OAAO,CAAC,gBAAgB,CAAC;AAC7B,MAAM;EAAEyB,MAAM;EAAEC;AAAM,CAAC,GAAG1B,OAAO,CAAC,aAAa,CAAC;AAChD,MAAM;EAAE2B;AAAS,CAAC,GAAG3B,OAAO,CAAC,eAAe,CAAC;AAE7C,MAAM4B,YAAY,GAAG,EAAE,GAAG,IAAI;AAC9B,MAAMC,QAAQ,GAAGC,MAAM,CAAC,UAAU,CAAC;AACnC,MAAMC,gBAAgB,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC;AAChC,MAAMC,WAAW,GAAG,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC;AAC/D,MAAMC,gBAAgB,GAAG,gCAAgC;;AAEzD;AACA;AACA;AACA;AACA;AACA,MAAMC,SAAS,SAASnC,YAAY,CAAC;EACnC;AACF;AACA;AACA;AACA;AACA;AACA;EACEoC,WAAWA,CAACC,OAAO,EAAEC,SAAS,EAAEC,OAAO,EAAE;IACvC,KAAK,CAAC,CAAC;IAEP,IAAI,CAACC,WAAW,GAAGzB,YAAY,CAAC,CAAC,CAAC;IAClC,IAAI,CAAC0B,UAAU,GAAG,IAAI;IACtB,IAAI,CAACC,mBAAmB,GAAG,KAAK;IAChC,IAAI,CAACC,eAAe,GAAG,KAAK;IAC5B,IAAI,CAACC,aAAa,GAAG5B,YAAY;IACjC,IAAI,CAAC6B,WAAW,GAAG,IAAI;IACvB,IAAI,CAACC,aAAa,GAAG,KAAK;IAC1B,IAAI,CAACC,WAAW,GAAG,CAAC,CAAC;IACrB,IAAI,CAACC,OAAO,GAAG,KAAK;IACpB,IAAI,CAACC,SAAS,GAAG,EAAE;IACnB,IAAI,CAACC,WAAW,GAAGf,SAAS,CAACgB,UAAU;IACvC,IAAI,CAACC,SAAS,GAAG,IAAI;IACrB,IAAI,CAACC,OAAO,GAAG,IAAI;IACnB,IAAI,CAACC,OAAO,GAAG,IAAI;IAEnB,IAAIjB,OAAO,KAAK,IAAI,EAAE;MACpB,IAAI,CAACkB,eAAe,GAAG,CAAC;MACxB,IAAI,CAACC,SAAS,GAAG,KAAK;MACtB,IAAI,CAACC,UAAU,GAAG,CAAC;MAEnB,IAAInB,SAAS,KAAKoB,SAAS,EAAE;QAC3BpB,SAAS,GAAG,EAAE;MAChB,CAAC,MAAM,IAAI,CAACqB,KAAK,CAACC,OAAO,CAACtB,SAAS,CAAC,EAAE;QACpC,IAAI,OAAOA,SAAS,KAAK,QAAQ,IAAIA,SAAS,KAAK,IAAI,EAAE;UACvDC,OAAO,GAAGD,SAAS;UACnBA,SAAS,GAAG,EAAE;QAChB,CAAC,MAAM;UACLA,SAAS,GAAG,CAACA,SAAS,CAAC;QACzB;MACF;MAEAuB,YAAY,CAAC,IAAI,EAAExB,OAAO,EAAEC,SAAS,EAAEC,OAAO,CAAC;IACjD,CAAC,MAAM;MACL,IAAI,CAACuB,SAAS,GAAGvB,OAAO,CAACwB,QAAQ;MACjC,IAAI,CAACP,SAAS,GAAG,IAAI;IACvB;EACF;;EAEA;AACF;AACA;AACA;AACA;AACA;EACE,IAAIQ,UAAUA,CAAA,EAAG;IACf,OAAO,IAAI,CAACxB,WAAW;EACzB;EAEA,IAAIwB,UAAUA,CAACC,IAAI,EAAE;IACnB,IAAI,CAAClD,YAAY,CAACmD,QAAQ,CAACD,IAAI,CAAC,EAAE;IAElC,IAAI,CAACzB,WAAW,GAAGyB,IAAI;;IAEvB;IACA;IACA;IACA,IAAI,IAAI,CAACb,SAAS,EAAE,IAAI,CAACA,SAAS,CAACZ,WAAW,GAAGyB,IAAI;EACvD;;EAEA;AACF;AACA;EACE,IAAIE,cAAcA,CAAA,EAAG;IACnB,IAAI,CAAC,IAAI,CAACb,OAAO,EAAE,OAAO,IAAI,CAACC,eAAe;IAE9C,OAAO,IAAI,CAACD,OAAO,CAACc,cAAc,CAACC,MAAM,GAAG,IAAI,CAAChB,OAAO,CAACiB,cAAc;EACzE;;EAEA;AACF;AACA;EACE,IAAIC,UAAUA,CAAA,EAAG;IACf,OAAOC,MAAM,CAACC,IAAI,CAAC,IAAI,CAAC1B,WAAW,CAAC,CAAC2B,IAAI,CAAC,CAAC;EAC7C;;EAEA;AACF;AACA;EACE,IAAIC,QAAQA,CAAA,EAAG;IACb,OAAO,IAAI,CAAC3B,OAAO;EACrB;;EAEA;AACF;AACA;EACE;EACA,IAAI4B,OAAOA,CAAA,EAAG;IACZ,OAAO,IAAI;EACb;;EAEA;AACF;AACA;EACE;EACA,IAAIC,OAAOA,CAAA,EAAG;IACZ,OAAO,IAAI;EACb;;EAEA;AACF;AACA;EACE;EACA,IAAIC,MAAMA,CAAA,EAAG;IACX,OAAO,IAAI;EACb;;EAEA;AACF;AACA;EACE;EACA,IAAIC,SAASA,CAAA,EAAG;IACd,OAAO,IAAI;EACb;;EAEA;AACF;AACA;EACE,IAAIC,QAAQA,CAAA,EAAG;IACb,OAAO,IAAI,CAAC/B,SAAS;EACvB;;EAEA;AACF;AACA;EACE,IAAIgC,UAAUA,CAAA,EAAG;IACf,OAAO,IAAI,CAAC/B,WAAW;EACzB;;EAEA;AACF;AACA;EACE,IAAIgC,GAAGA,CAAA,EAAG;IACR,OAAO,IAAI,CAACC,IAAI;EAClB;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEC,SAASA,CAACC,MAAM,EAAEC,IAAI,EAAE/C,OAAO,EAAE;IAC/B,MAAMgD,QAAQ,GAAG,IAAI3E,QAAQ,CAAC;MAC5B4E,sBAAsB,EAAEjD,OAAO,CAACiD,sBAAsB;MACtDxB,UAAU,EAAE,IAAI,CAACA,UAAU;MAC3BO,UAAU,EAAE,IAAI,CAACxB,WAAW;MAC5B0C,QAAQ,EAAE,IAAI,CAACjC,SAAS;MACxBkC,UAAU,EAAEnD,OAAO,CAACmD,UAAU;MAC9BC,kBAAkB,EAAEpD,OAAO,CAACoD;IAC9B,CAAC,CAAC;IAEF,MAAMC,MAAM,GAAG,IAAI/E,MAAM,CAACwE,MAAM,EAAE,IAAI,CAACtC,WAAW,EAAER,OAAO,CAACsD,YAAY,CAAC;IAEzE,IAAI,CAACzC,SAAS,GAAGmC,QAAQ;IACzB,IAAI,CAAClC,OAAO,GAAGuC,MAAM;IACrB,IAAI,CAACtC,OAAO,GAAG+B,MAAM;IAErBE,QAAQ,CAAClE,UAAU,CAAC,GAAG,IAAI;IAC3BuE,MAAM,CAACvE,UAAU,CAAC,GAAG,IAAI;IACzBgE,MAAM,CAAChE,UAAU,CAAC,GAAG,IAAI;IAEzBkE,QAAQ,CAACO,EAAE,CAAC,UAAU,EAAEC,kBAAkB,CAAC;IAC3CR,QAAQ,CAACO,EAAE,CAAC,OAAO,EAAEE,eAAe,CAAC;IACrCT,QAAQ,CAACO,EAAE,CAAC,OAAO,EAAEG,eAAe,CAAC;IACrCV,QAAQ,CAACO,EAAE,CAAC,SAAS,EAAEI,iBAAiB,CAAC;IACzCX,QAAQ,CAACO,EAAE,CAAC,MAAM,EAAEK,cAAc,CAAC;IACnCZ,QAAQ,CAACO,EAAE,CAAC,MAAM,EAAEM,cAAc,CAAC;IAEnCR,MAAM,CAACf,OAAO,GAAGwB,aAAa;;IAE9B;IACA;IACA;IACA,IAAIhB,MAAM,CAACiB,UAAU,EAAEjB,MAAM,CAACiB,UAAU,CAAC,CAAC,CAAC;IAC3C,IAAIjB,MAAM,CAACkB,UAAU,EAAElB,MAAM,CAACkB,UAAU,CAAC,CAAC;IAE1C,IAAIjB,IAAI,CAACjB,MAAM,GAAG,CAAC,EAAEgB,MAAM,CAACmB,OAAO,CAAClB,IAAI,CAAC;IAEzCD,MAAM,CAACS,EAAE,CAAC,OAAO,EAAEW,aAAa,CAAC;IACjCpB,MAAM,CAACS,EAAE,CAAC,MAAM,EAAEY,YAAY,CAAC;IAC/BrB,MAAM,CAACS,EAAE,CAAC,KAAK,EAAEa,WAAW,CAAC;IAC7BtB,MAAM,CAACS,EAAE,CAAC,OAAO,EAAEc,aAAa,CAAC;IAEjC,IAAI,CAAC1D,WAAW,GAAGf,SAAS,CAAC0E,IAAI;IACjC,IAAI,CAACC,IAAI,CAAC,MAAM,CAAC;EACnB;;EAEA;AACF;AACA;AACA;AACA;EACEC,SAASA,CAAA,EAAG;IACV,IAAI,CAAC,IAAI,CAACzD,OAAO,EAAE;MACjB,IAAI,CAACJ,WAAW,GAAGf,SAAS,CAAC6E,MAAM;MACnC,IAAI,CAACF,IAAI,CAAC,OAAO,EAAE,IAAI,CAACrE,UAAU,EAAE,IAAI,CAACG,aAAa,CAAC;MACvD;IACF;IAEA,IAAI,IAAI,CAACG,WAAW,CAACpC,iBAAiB,CAACsG,aAAa,CAAC,EAAE;MACrD,IAAI,CAAClE,WAAW,CAACpC,iBAAiB,CAACsG,aAAa,CAAC,CAACC,OAAO,CAAC,CAAC;IAC7D;IAEA,IAAI,CAAC9D,SAAS,CAAC+D,kBAAkB,CAAC,CAAC;IACnC,IAAI,CAACjE,WAAW,GAAGf,SAAS,CAAC6E,MAAM;IACnC,IAAI,CAACF,IAAI,CAAC,OAAO,EAAE,IAAI,CAACrE,UAAU,EAAE,IAAI,CAACG,aAAa,CAAC;EACzD;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEwE,KAAKA,CAACC,IAAI,EAAEC,IAAI,EAAE;IAChB,IAAI,IAAI,CAACrC,UAAU,KAAK9C,SAAS,CAAC6E,MAAM,EAAE;IAC1C,IAAI,IAAI,CAAC/B,UAAU,KAAK9C,SAAS,CAACgB,UAAU,EAAE;MAC5C,MAAMoE,GAAG,GAAG,4DAA4D;MACxEC,cAAc,CAAC,IAAI,EAAE,IAAI,CAACC,IAAI,EAAEF,GAAG,CAAC;MACpC;IACF;IAEA,IAAI,IAAI,CAACtC,UAAU,KAAK9C,SAAS,CAACuF,OAAO,EAAE;MACzC,IACE,IAAI,CAAC/E,eAAe,KACnB,IAAI,CAACD,mBAAmB,IAAI,IAAI,CAACU,SAAS,CAACgB,cAAc,CAACuD,YAAY,CAAC,EACxE;QACA,IAAI,CAACrE,OAAO,CAACsE,GAAG,CAAC,CAAC;MACpB;MAEA;IACF;IAEA,IAAI,CAAC1E,WAAW,GAAGf,SAAS,CAACuF,OAAO;IACpC,IAAI,CAACrE,OAAO,CAAC+D,KAAK,CAACC,IAAI,EAAEC,IAAI,EAAE,CAAC,IAAI,CAAC9D,SAAS,EAAGqE,GAAG,IAAK;MACvD;MACA;MACA;MACA;MACA,IAAIA,GAAG,EAAE;MAET,IAAI,CAAClF,eAAe,GAAG,IAAI;MAE3B,IACE,IAAI,CAACD,mBAAmB,IACxB,IAAI,CAACU,SAAS,CAACgB,cAAc,CAACuD,YAAY,EAC1C;QACA,IAAI,CAACrE,OAAO,CAACsE,GAAG,CAAC,CAAC;MACpB;IACF,CAAC,CAAC;IAEFE,aAAa,CAAC,IAAI,CAAC;EACrB;;EAEA;AACF;AACA;AACA;AACA;EACEC,KAAKA,CAAA,EAAG;IACN,IACE,IAAI,CAAC9C,UAAU,KAAK9C,SAAS,CAACgB,UAAU,IACxC,IAAI,CAAC8B,UAAU,KAAK9C,SAAS,CAAC6E,MAAM,EACpC;MACA;IACF;IAEA,IAAI,CAAChE,OAAO,GAAG,IAAI;IACnB,IAAI,CAACM,OAAO,CAACyE,KAAK,CAAC,CAAC;EACtB;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;EACEC,IAAIA,CAACV,IAAI,EAAEW,IAAI,EAAEC,EAAE,EAAE;IACnB,IAAI,IAAI,CAACjD,UAAU,KAAK9C,SAAS,CAACgB,UAAU,EAAE;MAC5C,MAAM,IAAIgF,KAAK,CAAC,kDAAkD,CAAC;IACrE;IAEA,IAAI,OAAOb,IAAI,KAAK,UAAU,EAAE;MAC9BY,EAAE,GAAGZ,IAAI;MACTA,IAAI,GAAGW,IAAI,GAAGvE,SAAS;IACzB,CAAC,MAAM,IAAI,OAAOuE,IAAI,KAAK,UAAU,EAAE;MACrCC,EAAE,GAAGD,IAAI;MACTA,IAAI,GAAGvE,SAAS;IAClB;IAEA,IAAI,OAAO4D,IAAI,KAAK,QAAQ,EAAEA,IAAI,GAAGA,IAAI,CAACc,QAAQ,CAAC,CAAC;IAEpD,IAAI,IAAI,CAACnD,UAAU,KAAK9C,SAAS,CAAC0E,IAAI,EAAE;MACtCwB,cAAc,CAAC,IAAI,EAAEf,IAAI,EAAEY,EAAE,CAAC;MAC9B;IACF;IAEA,IAAID,IAAI,KAAKvE,SAAS,EAAEuE,IAAI,GAAG,CAAC,IAAI,CAACzE,SAAS;IAC9C,IAAI,CAACH,OAAO,CAAC2E,IAAI,CAACV,IAAI,IAAItG,YAAY,EAAEiH,IAAI,EAAEC,EAAE,CAAC;EACnD;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;EACEI,IAAIA,CAAChB,IAAI,EAAEW,IAAI,EAAEC,EAAE,EAAE;IACnB,IAAI,IAAI,CAACjD,UAAU,KAAK9C,SAAS,CAACgB,UAAU,EAAE;MAC5C,MAAM,IAAIgF,KAAK,CAAC,kDAAkD,CAAC;IACrE;IAEA,IAAI,OAAOb,IAAI,KAAK,UAAU,EAAE;MAC9BY,EAAE,GAAGZ,IAAI;MACTA,IAAI,GAAGW,IAAI,GAAGvE,SAAS;IACzB,CAAC,MAAM,IAAI,OAAOuE,IAAI,KAAK,UAAU,EAAE;MACrCC,EAAE,GAAGD,IAAI;MACTA,IAAI,GAAGvE,SAAS;IAClB;IAEA,IAAI,OAAO4D,IAAI,KAAK,QAAQ,EAAEA,IAAI,GAAGA,IAAI,CAACc,QAAQ,CAAC,CAAC;IAEpD,IAAI,IAAI,CAACnD,UAAU,KAAK9C,SAAS,CAAC0E,IAAI,EAAE;MACtCwB,cAAc,CAAC,IAAI,EAAEf,IAAI,EAAEY,EAAE,CAAC;MAC9B;IACF;IAEA,IAAID,IAAI,KAAKvE,SAAS,EAAEuE,IAAI,GAAG,CAAC,IAAI,CAACzE,SAAS;IAC9C,IAAI,CAACH,OAAO,CAACiF,IAAI,CAAChB,IAAI,IAAItG,YAAY,EAAEiH,IAAI,EAAEC,EAAE,CAAC;EACnD;;EAEA;AACF;AACA;AACA;AACA;EACEK,MAAMA,CAAA,EAAG;IACP,IACE,IAAI,CAACtD,UAAU,KAAK9C,SAAS,CAACgB,UAAU,IACxC,IAAI,CAAC8B,UAAU,KAAK9C,SAAS,CAAC6E,MAAM,EACpC;MACA;IACF;IAEA,IAAI,CAAChE,OAAO,GAAG,KAAK;IACpB,IAAI,CAAC,IAAI,CAACI,SAAS,CAACgB,cAAc,CAACoE,SAAS,EAAE,IAAI,CAAClF,OAAO,CAACiF,MAAM,CAAC,CAAC;EACrE;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEE,IAAIA,CAACnB,IAAI,EAAE/E,OAAO,EAAE2F,EAAE,EAAE;IACtB,IAAI,IAAI,CAACjD,UAAU,KAAK9C,SAAS,CAACgB,UAAU,EAAE;MAC5C,MAAM,IAAIgF,KAAK,CAAC,kDAAkD,CAAC;IACrE;IAEA,IAAI,OAAO5F,OAAO,KAAK,UAAU,EAAE;MACjC2F,EAAE,GAAG3F,OAAO;MACZA,OAAO,GAAG,CAAC,CAAC;IACd;IAEA,IAAI,OAAO+E,IAAI,KAAK,QAAQ,EAAEA,IAAI,GAAGA,IAAI,CAACc,QAAQ,CAAC,CAAC;IAEpD,IAAI,IAAI,CAACnD,UAAU,KAAK9C,SAAS,CAAC0E,IAAI,EAAE;MACtCwB,cAAc,CAAC,IAAI,EAAEf,IAAI,EAAEY,EAAE,CAAC;MAC9B;IACF;IAEA,MAAMQ,IAAI,GAAG;MACXC,MAAM,EAAE,OAAOrB,IAAI,KAAK,QAAQ;MAChCW,IAAI,EAAE,CAAC,IAAI,CAACzE,SAAS;MACrBoF,QAAQ,EAAE,IAAI;MACdC,GAAG,EAAE,IAAI;MACT,GAAGtG;IACL,CAAC;IAED,IAAI,CAAC,IAAI,CAACQ,WAAW,CAACpC,iBAAiB,CAACsG,aAAa,CAAC,EAAE;MACtDyB,IAAI,CAACE,QAAQ,GAAG,KAAK;IACvB;IAEA,IAAI,CAACvF,OAAO,CAACoF,IAAI,CAACnB,IAAI,IAAItG,YAAY,EAAE0H,IAAI,EAAER,EAAE,CAAC;EACnD;;EAEA;AACF;AACA;AACA;AACA;EACEY,SAASA,CAAA,EAAG;IACV,IAAI,IAAI,CAAC7D,UAAU,KAAK9C,SAAS,CAAC6E,MAAM,EAAE;IAC1C,IAAI,IAAI,CAAC/B,UAAU,KAAK9C,SAAS,CAACgB,UAAU,EAAE;MAC5C,MAAMoE,GAAG,GAAG,4DAA4D;MACxEC,cAAc,CAAC,IAAI,EAAE,IAAI,CAACC,IAAI,EAAEF,GAAG,CAAC;MACpC;IACF;IAEA,IAAI,IAAI,CAACjE,OAAO,EAAE;MAChB,IAAI,CAACJ,WAAW,GAAGf,SAAS,CAACuF,OAAO;MACpC,IAAI,CAACpE,OAAO,CAACyF,OAAO,CAAC,CAAC;IACxB;EACF;AACF;;AAEA;AACA;AACA;AACA;AACAvE,MAAM,CAACwE,cAAc,CAAC7G,SAAS,EAAE,YAAY,EAAE;EAC7C8G,UAAU,EAAE,IAAI;EAChBC,KAAK,EAAEjH,WAAW,CAACkH,OAAO,CAAC,YAAY;AACzC,CAAC,CAAC;;AAEF;AACA;AACA;AACA;AACA3E,MAAM,CAACwE,cAAc,CAAC7G,SAAS,CAACiH,SAAS,EAAE,YAAY,EAAE;EACvDH,UAAU,EAAE,IAAI;EAChBC,KAAK,EAAEjH,WAAW,CAACkH,OAAO,CAAC,YAAY;AACzC,CAAC,CAAC;;AAEF;AACA;AACA;AACA;AACA3E,MAAM,CAACwE,cAAc,CAAC7G,SAAS,EAAE,MAAM,EAAE;EACvC8G,UAAU,EAAE,IAAI;EAChBC,KAAK,EAAEjH,WAAW,CAACkH,OAAO,CAAC,MAAM;AACnC,CAAC,CAAC;;AAEF;AACA;AACA;AACA;AACA3E,MAAM,CAACwE,cAAc,CAAC7G,SAAS,CAACiH,SAAS,EAAE,MAAM,EAAE;EACjDH,UAAU,EAAE,IAAI;EAChBC,KAAK,EAAEjH,WAAW,CAACkH,OAAO,CAAC,MAAM;AACnC,CAAC,CAAC;;AAEF;AACA;AACA;AACA;AACA3E,MAAM,CAACwE,cAAc,CAAC7G,SAAS,EAAE,SAAS,EAAE;EAC1C8G,UAAU,EAAE,IAAI;EAChBC,KAAK,EAAEjH,WAAW,CAACkH,OAAO,CAAC,SAAS;AACtC,CAAC,CAAC;;AAEF;AACA;AACA;AACA;AACA3E,MAAM,CAACwE,cAAc,CAAC7G,SAAS,CAACiH,SAAS,EAAE,SAAS,EAAE;EACpDH,UAAU,EAAE,IAAI;EAChBC,KAAK,EAAEjH,WAAW,CAACkH,OAAO,CAAC,SAAS;AACtC,CAAC,CAAC;;AAEF;AACA;AACA;AACA;AACA3E,MAAM,CAACwE,cAAc,CAAC7G,SAAS,EAAE,QAAQ,EAAE;EACzC8G,UAAU,EAAE,IAAI;EAChBC,KAAK,EAAEjH,WAAW,CAACkH,OAAO,CAAC,QAAQ;AACrC,CAAC,CAAC;;AAEF;AACA;AACA;AACA;AACA3E,MAAM,CAACwE,cAAc,CAAC7G,SAAS,CAACiH,SAAS,EAAE,QAAQ,EAAE;EACnDH,UAAU,EAAE,IAAI;EAChBC,KAAK,EAAEjH,WAAW,CAACkH,OAAO,CAAC,QAAQ;AACrC,CAAC,CAAC;AAEF,CACE,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,UAAU,EACV,YAAY,EACZ,KAAK,CACN,CAACE,OAAO,CAAEC,QAAQ,IAAK;EACtB9E,MAAM,CAACwE,cAAc,CAAC7G,SAAS,CAACiH,SAAS,EAAEE,QAAQ,EAAE;IAAEL,UAAU,EAAE;EAAK,CAAC,CAAC;AAC5E,CAAC,CAAC;;AAEF;AACA;AACA;AACA;AACA,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,CAACI,OAAO,CAAEE,MAAM,IAAK;EACxD/E,MAAM,CAACwE,cAAc,CAAC7G,SAAS,CAACiH,SAAS,EAAE,KAAKG,MAAM,EAAE,EAAE;IACxDN,UAAU,EAAE,IAAI;IAChBO,GAAGA,CAAA,EAAG;MACJ,KAAK,MAAMC,QAAQ,IAAI,IAAI,CAACC,SAAS,CAACH,MAAM,CAAC,EAAE;QAC7C,IAAIE,QAAQ,CAACvI,oBAAoB,CAAC,EAAE,OAAOuI,QAAQ,CAACtI,SAAS,CAAC;MAChE;MAEA,OAAO,IAAI;IACb,CAAC;IACDwI,GAAGA,CAACC,OAAO,EAAE;MACX,KAAK,MAAMH,QAAQ,IAAI,IAAI,CAACC,SAAS,CAACH,MAAM,CAAC,EAAE;QAC7C,IAAIE,QAAQ,CAACvI,oBAAoB,CAAC,EAAE;UAClC,IAAI,CAAC2I,cAAc,CAACN,MAAM,EAAEE,QAAQ,CAAC;UACrC;QACF;MACF;MAEA,IAAI,OAAOG,OAAO,KAAK,UAAU,EAAE;MAEnC,IAAI,CAACpI,gBAAgB,CAAC+H,MAAM,EAAEK,OAAO,EAAE;QACrC,CAAC1I,oBAAoB,GAAG;MAC1B,CAAC,CAAC;IACJ;EACF,CAAC,CAAC;AACJ,CAAC,CAAC;AAEFiB,SAAS,CAACiH,SAAS,CAAC5H,gBAAgB,GAAGA,gBAAgB;AACvDW,SAAS,CAACiH,SAAS,CAAC3H,mBAAmB,GAAGA,mBAAmB;AAE7DqI,MAAM,CAACC,OAAO,GAAG5H,SAAS;;AAE1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS0B,YAAYA,CAACmG,SAAS,EAAE3H,OAAO,EAAEC,SAAS,EAAEC,OAAO,EAAE;EAC5D,MAAMmG,IAAI,GAAG;IACXlD,sBAAsB,EAAE,IAAI;IAC5BzB,QAAQ,EAAE,IAAI;IACdkG,eAAe,EAAEjI,gBAAgB,CAAC,CAAC,CAAC;IACpC0D,UAAU,EAAE,GAAG,GAAG,IAAI,GAAG,IAAI;IAC7BC,kBAAkB,EAAE,KAAK;IACzBuE,iBAAiB,EAAE,IAAI;IACvBC,eAAe,EAAE,KAAK;IACtBC,YAAY,EAAE,EAAE;IAChB,GAAG7H,OAAO;IACV8H,UAAU,EAAE3G,SAAS;IACrB4G,QAAQ,EAAE5G,SAAS;IACnBsB,QAAQ,EAAEtB,SAAS;IACnB6G,OAAO,EAAE7G,SAAS;IAClB6F,MAAM,EAAE,KAAK;IACbiB,IAAI,EAAE9G,SAAS;IACf+G,IAAI,EAAE/G,SAAS;IACfgH,IAAI,EAAEhH;EACR,CAAC;EAEDsG,SAAS,CAAClG,SAAS,GAAG4E,IAAI,CAAC3E,QAAQ;EAEnC,IAAI,CAAC/B,gBAAgB,CAACkC,QAAQ,CAACwE,IAAI,CAACuB,eAAe,CAAC,EAAE;IACpD,MAAM,IAAIU,UAAU,CAClB,iCAAiCjC,IAAI,CAACuB,eAAe,GAAG,GACtD,wBAAwBjI,gBAAgB,CAAC0C,IAAI,CAAC,IAAI,CAAC,GACvD,CAAC;EACH;EAEA,IAAIkG,SAAS;EAEb,IAAIvI,OAAO,YAAY3B,GAAG,EAAE;IAC1BkK,SAAS,GAAGvI,OAAO;EACrB,CAAC,MAAM;IACL,IAAI;MACFuI,SAAS,GAAG,IAAIlK,GAAG,CAAC2B,OAAO,CAAC;IAC9B,CAAC,CAAC,OAAOwI,CAAC,EAAE;MACV,MAAM,IAAIC,WAAW,CAAC,gBAAgBzI,OAAO,EAAE,CAAC;IAClD;EACF;EAEA,IAAIuI,SAAS,CAAC5F,QAAQ,KAAK,OAAO,EAAE;IAClC4F,SAAS,CAAC5F,QAAQ,GAAG,KAAK;EAC5B,CAAC,MAAM,IAAI4F,SAAS,CAAC5F,QAAQ,KAAK,QAAQ,EAAE;IAC1C4F,SAAS,CAAC5F,QAAQ,GAAG,MAAM;EAC7B;EAEAgF,SAAS,CAAC7E,IAAI,GAAGyF,SAAS,CAACG,IAAI;EAE/B,MAAMC,QAAQ,GAAGJ,SAAS,CAAC5F,QAAQ,KAAK,MAAM;EAC9C,MAAMiG,QAAQ,GAAGL,SAAS,CAAC5F,QAAQ,KAAK,UAAU;EAClD,IAAIkG,iBAAiB;EAErB,IAAIN,SAAS,CAAC5F,QAAQ,KAAK,KAAK,IAAI,CAACgG,QAAQ,IAAI,CAACC,QAAQ,EAAE;IAC1DC,iBAAiB,GACf,oDAAoD,GACpD,iCAAiC;EACrC,CAAC,MAAM,IAAID,QAAQ,IAAI,CAACL,SAAS,CAACO,QAAQ,EAAE;IAC1CD,iBAAiB,GAAG,6BAA6B;EACnD,CAAC,MAAM,IAAIN,SAAS,CAACQ,IAAI,EAAE;IACzBF,iBAAiB,GAAG,wCAAwC;EAC9D;EAEA,IAAIA,iBAAiB,EAAE;IACrB,MAAMrD,GAAG,GAAG,IAAIiD,WAAW,CAACI,iBAAiB,CAAC;IAE9C,IAAIlB,SAAS,CAACvG,UAAU,KAAK,CAAC,EAAE;MAC9B,MAAMoE,GAAG;IACX,CAAC,MAAM;MACLwD,iBAAiB,CAACrB,SAAS,EAAEnC,GAAG,CAAC;MACjC;IACF;EACF;EAEA,MAAMyD,WAAW,GAAGN,QAAQ,GAAG,GAAG,GAAG,EAAE;EACvC,MAAMO,GAAG,GAAGjL,WAAW,CAAC,EAAE,CAAC,CAAC8H,QAAQ,CAAC,QAAQ,CAAC;EAC9C,MAAMoD,OAAO,GAAGR,QAAQ,GAAG9K,KAAK,CAACsL,OAAO,GAAGrL,IAAI,CAACqL,OAAO;EACvD,MAAMC,WAAW,GAAG,IAAIC,GAAG,CAAC,CAAC;EAC7B,IAAIxB,iBAAiB;EAErBxB,IAAI,CAACiD,gBAAgB,GACnBjD,IAAI,CAACiD,gBAAgB,KAAKX,QAAQ,GAAGY,UAAU,GAAGC,UAAU,CAAC;EAC/DnD,IAAI,CAAC4C,WAAW,GAAG5C,IAAI,CAAC4C,WAAW,IAAIA,WAAW;EAClD5C,IAAI,CAACgC,IAAI,GAAGE,SAAS,CAACF,IAAI,IAAIY,WAAW;EACzC5C,IAAI,CAAC8B,IAAI,GAAGI,SAAS,CAACN,QAAQ,CAACwB,UAAU,CAAC,GAAG,CAAC,GAC1ClB,SAAS,CAACN,QAAQ,CAACyB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAC/BnB,SAAS,CAACN,QAAQ;EACtB5B,IAAI,CAACsD,OAAO,GAAG;IACb,GAAGtD,IAAI,CAACsD,OAAO;IACf,uBAAuB,EAAEtD,IAAI,CAACuB,eAAe;IAC7C,mBAAmB,EAAEsB,GAAG;IACxBU,UAAU,EAAE,SAAS;IACrBC,OAAO,EAAE;EACX,CAAC;EACDxD,IAAI,CAAC+B,IAAI,GAAGG,SAAS,CAACO,QAAQ,GAAGP,SAAS,CAACuB,MAAM;EACjDzD,IAAI,CAAC6B,OAAO,GAAG7B,IAAI,CAAC0D,gBAAgB;EAEpC,IAAI1D,IAAI,CAACwB,iBAAiB,EAAE;IAC1BA,iBAAiB,GAAG,IAAIvJ,iBAAiB,CACvC+H,IAAI,CAACwB,iBAAiB,KAAK,IAAI,GAAGxB,IAAI,CAACwB,iBAAiB,GAAG,CAAC,CAAC,EAC7D,KAAK,EACLxB,IAAI,CAAChD,UACP,CAAC;IACDgD,IAAI,CAACsD,OAAO,CAAC,0BAA0B,CAAC,GAAGtK,MAAM,CAAC;MAChD,CAACf,iBAAiB,CAACsG,aAAa,GAAGiD,iBAAiB,CAACmC,KAAK,CAAC;IAC7D,CAAC,CAAC;EACJ;EACA,IAAI/J,SAAS,CAAC+B,MAAM,EAAE;IACpB,KAAK,MAAMW,QAAQ,IAAI1C,SAAS,EAAE;MAChC,IACE,OAAO0C,QAAQ,KAAK,QAAQ,IAC5B,CAAC9C,gBAAgB,CAACoK,IAAI,CAACtH,QAAQ,CAAC,IAChCyG,WAAW,CAACc,GAAG,CAACvH,QAAQ,CAAC,EACzB;QACA,MAAM,IAAI8F,WAAW,CACnB,oDACF,CAAC;MACH;MAEAW,WAAW,CAACe,GAAG,CAACxH,QAAQ,CAAC;IAC3B;IAEA0D,IAAI,CAACsD,OAAO,CAAC,wBAAwB,CAAC,GAAG1J,SAAS,CAACoC,IAAI,CAAC,GAAG,CAAC;EAC9D;EACA,IAAIgE,IAAI,CAAC+D,MAAM,EAAE;IACf,IAAI/D,IAAI,CAACuB,eAAe,GAAG,EAAE,EAAE;MAC7BvB,IAAI,CAACsD,OAAO,CAAC,sBAAsB,CAAC,GAAGtD,IAAI,CAAC+D,MAAM;IACpD,CAAC,MAAM;MACL/D,IAAI,CAACsD,OAAO,CAACU,MAAM,GAAGhE,IAAI,CAAC+D,MAAM;IACnC;EACF;EACA,IAAI7B,SAAS,CAAC+B,QAAQ,IAAI/B,SAAS,CAACgC,QAAQ,EAAE;IAC5ClE,IAAI,CAACmE,IAAI,GAAG,GAAGjC,SAAS,CAAC+B,QAAQ,IAAI/B,SAAS,CAACgC,QAAQ,EAAE;EAC3D;EAEA,IAAI3B,QAAQ,EAAE;IACZ,MAAM6B,KAAK,GAAGpE,IAAI,CAAC+B,IAAI,CAACsC,KAAK,CAAC,GAAG,CAAC;IAElCrE,IAAI,CAAC2B,UAAU,GAAGyC,KAAK,CAAC,CAAC,CAAC;IAC1BpE,IAAI,CAAC+B,IAAI,GAAGqC,KAAK,CAAC,CAAC,CAAC;EACtB;EAEA,IAAIE,GAAG;EAEP,IAAItE,IAAI,CAACyB,eAAe,EAAE;IACxB,IAAIH,SAAS,CAACvG,UAAU,KAAK,CAAC,EAAE;MAC9BuG,SAAS,CAACiD,YAAY,GAAGhC,QAAQ;MACjCjB,SAAS,CAACkD,eAAe,GAAGlC,QAAQ;MACpChB,SAAS,CAACmD,yBAAyB,GAAGlC,QAAQ,GAC1CvC,IAAI,CAAC2B,UAAU,GACfO,SAAS,CAACJ,IAAI;MAElB,MAAMwB,OAAO,GAAGzJ,OAAO,IAAIA,OAAO,CAACyJ,OAAO;;MAE1C;MACA;MACA;MACA;MACAzJ,OAAO,GAAG;QAAE,GAAGA,OAAO;QAAEyJ,OAAO,EAAE,CAAC;MAAE,CAAC;MAErC,IAAIA,OAAO,EAAE;QACX,KAAK,MAAM,CAACT,GAAG,EAAErC,KAAK,CAAC,IAAI1E,MAAM,CAAC4I,OAAO,CAACpB,OAAO,CAAC,EAAE;UAClDzJ,OAAO,CAACyJ,OAAO,CAACT,GAAG,CAAC8B,WAAW,CAAC,CAAC,CAAC,GAAGnE,KAAK;QAC5C;MACF;IACF,CAAC,MAAM,IAAIc,SAAS,CAACsD,aAAa,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE;MACpD,MAAMC,UAAU,GAAGtC,QAAQ,GACvBjB,SAAS,CAACiD,YAAY,GACpBvE,IAAI,CAAC2B,UAAU,KAAKL,SAAS,CAACmD,yBAAyB,GACvD,KAAK,GACPnD,SAAS,CAACiD,YAAY,GACpB,KAAK,GACLrC,SAAS,CAACJ,IAAI,KAAKR,SAAS,CAACmD,yBAAyB;MAE5D,IAAI,CAACI,UAAU,IAAKvD,SAAS,CAACkD,eAAe,IAAI,CAAClC,QAAS,EAAE;QAC3D;QACA;QACA;QACA;QACA,OAAOtC,IAAI,CAACsD,OAAO,CAACwB,aAAa;QACjC,OAAO9E,IAAI,CAACsD,OAAO,CAACyB,MAAM;QAE1B,IAAI,CAACF,UAAU,EAAE,OAAO7E,IAAI,CAACsD,OAAO,CAACxB,IAAI;QAEzC9B,IAAI,CAACmE,IAAI,GAAGnJ,SAAS;MACvB;IACF;;IAEA;IACA;IACA;IACA;IACA;IACA,IAAIgF,IAAI,CAACmE,IAAI,IAAI,CAACtK,OAAO,CAACyJ,OAAO,CAACwB,aAAa,EAAE;MAC/CjL,OAAO,CAACyJ,OAAO,CAACwB,aAAa,GAC3B,QAAQ,GAAGE,MAAM,CAACC,IAAI,CAACjF,IAAI,CAACmE,IAAI,CAAC,CAACzE,QAAQ,CAAC,QAAQ,CAAC;IACxD;IAEA4E,GAAG,GAAGhD,SAAS,CAACvC,IAAI,GAAG+D,OAAO,CAAC9C,IAAI,CAAC;IAEpC,IAAIsB,SAAS,CAACvG,UAAU,EAAE;MACxB;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACAuG,SAAS,CAAClD,IAAI,CAAC,UAAU,EAAEkD,SAAS,CAAC9E,GAAG,EAAE8H,GAAG,CAAC;IAChD;EACF,CAAC,MAAM;IACLA,GAAG,GAAGhD,SAAS,CAACvC,IAAI,GAAG+D,OAAO,CAAC9C,IAAI,CAAC;EACtC;EAEA,IAAIA,IAAI,CAAC6B,OAAO,EAAE;IAChByC,GAAG,CAAClH,EAAE,CAAC,SAAS,EAAE,MAAM;MACtB0B,cAAc,CAACwC,SAAS,EAAEgD,GAAG,EAAE,iCAAiC,CAAC;IACnE,CAAC,CAAC;EACJ;EAEAA,GAAG,CAAClH,EAAE,CAAC,OAAO,EAAG+B,GAAG,IAAK;IACvB,IAAImF,GAAG,KAAK,IAAI,IAAIA,GAAG,CAAClL,QAAQ,CAAC,EAAE;IAEnCkL,GAAG,GAAGhD,SAAS,CAACvC,IAAI,GAAG,IAAI;IAC3B4D,iBAAiB,CAACrB,SAAS,EAAEnC,GAAG,CAAC;EACnC,CAAC,CAAC;EAEFmF,GAAG,CAAClH,EAAE,CAAC,UAAU,EAAG8H,GAAG,IAAK;IAC1B,MAAMC,QAAQ,GAAGD,GAAG,CAAC5B,OAAO,CAAC6B,QAAQ;IACrC,MAAMC,UAAU,GAAGF,GAAG,CAACE,UAAU;IAEjC,IACED,QAAQ,IACRnF,IAAI,CAACyB,eAAe,IACpB2D,UAAU,IAAI,GAAG,IACjBA,UAAU,GAAG,GAAG,EAChB;MACA,IAAI,EAAE9D,SAAS,CAACvG,UAAU,GAAGiF,IAAI,CAAC0B,YAAY,EAAE;QAC9C5C,cAAc,CAACwC,SAAS,EAAEgD,GAAG,EAAE,4BAA4B,CAAC;QAC5D;MACF;MAEAA,GAAG,CAACe,KAAK,CAAC,CAAC;MAEX,IAAIC,IAAI;MAER,IAAI;QACFA,IAAI,GAAG,IAAItN,GAAG,CAACmN,QAAQ,EAAExL,OAAO,CAAC;MACnC,CAAC,CAAC,OAAOwI,CAAC,EAAE;QACV,MAAMhD,GAAG,GAAG,IAAIiD,WAAW,CAAC,gBAAgB+C,QAAQ,EAAE,CAAC;QACvDxC,iBAAiB,CAACrB,SAAS,EAAEnC,GAAG,CAAC;QACjC;MACF;MAEAhE,YAAY,CAACmG,SAAS,EAAEgE,IAAI,EAAE1L,SAAS,EAAEC,OAAO,CAAC;IACnD,CAAC,MAAM,IAAI,CAACyH,SAAS,CAAClD,IAAI,CAAC,qBAAqB,EAAEkG,GAAG,EAAEY,GAAG,CAAC,EAAE;MAC3DpG,cAAc,CACZwC,SAAS,EACTgD,GAAG,EACH,+BAA+BY,GAAG,CAACE,UAAU,EAC/C,CAAC;IACH;EACF,CAAC,CAAC;EAEFd,GAAG,CAAClH,EAAE,CAAC,SAAS,EAAE,CAAC8H,GAAG,EAAEvI,MAAM,EAAEC,IAAI,KAAK;IACvC0E,SAAS,CAAClD,IAAI,CAAC,SAAS,EAAE8G,GAAG,CAAC;;IAE9B;IACA;IACA;IACA;IACA,IAAI5D,SAAS,CAAC/E,UAAU,KAAK9C,SAAS,CAACgB,UAAU,EAAE;IAEnD6J,GAAG,GAAGhD,SAAS,CAACvC,IAAI,GAAG,IAAI;IAE3B,MAAMwG,OAAO,GAAGL,GAAG,CAAC5B,OAAO,CAACiC,OAAO;IAEnC,IAAIA,OAAO,KAAKvK,SAAS,IAAIuK,OAAO,CAACZ,WAAW,CAAC,CAAC,KAAK,WAAW,EAAE;MAClE7F,cAAc,CAACwC,SAAS,EAAE3E,MAAM,EAAE,wBAAwB,CAAC;MAC3D;IACF;IAEA,MAAM6I,MAAM,GAAG3N,UAAU,CAAC,MAAM,CAAC,CAC9B4N,MAAM,CAAC5C,GAAG,GAAGtK,IAAI,CAAC,CAClBiN,MAAM,CAAC,QAAQ,CAAC;IAEnB,IAAIN,GAAG,CAAC5B,OAAO,CAAC,sBAAsB,CAAC,KAAKkC,MAAM,EAAE;MAClD1G,cAAc,CAACwC,SAAS,EAAE3E,MAAM,EAAE,qCAAqC,CAAC;MACxE;IACF;IAEA,MAAM+I,UAAU,GAAGR,GAAG,CAAC5B,OAAO,CAAC,wBAAwB,CAAC;IACxD,IAAIqC,SAAS;IAEb,IAAID,UAAU,KAAK1K,SAAS,EAAE;MAC5B,IAAI,CAAC+H,WAAW,CAAC6C,IAAI,EAAE;QACrBD,SAAS,GAAG,kDAAkD;MAChE,CAAC,MAAM,IAAI,CAAC5C,WAAW,CAACc,GAAG,CAAC6B,UAAU,CAAC,EAAE;QACvCC,SAAS,GAAG,oCAAoC;MAClD;IACF,CAAC,MAAM,IAAI5C,WAAW,CAAC6C,IAAI,EAAE;MAC3BD,SAAS,GAAG,4BAA4B;IAC1C;IAEA,IAAIA,SAAS,EAAE;MACb7G,cAAc,CAACwC,SAAS,EAAE3E,MAAM,EAAEgJ,SAAS,CAAC;MAC5C;IACF;IAEA,IAAID,UAAU,EAAEpE,SAAS,CAAC/G,SAAS,GAAGmL,UAAU;IAEhD,MAAMG,sBAAsB,GAAGX,GAAG,CAAC5B,OAAO,CAAC,0BAA0B,CAAC;IAEtE,IAAIuC,sBAAsB,KAAK7K,SAAS,EAAE;MACxC,IAAI,CAACwG,iBAAiB,EAAE;QACtB,MAAMsE,OAAO,GACX,iEAAiE,GACjE,eAAe;QACjBhH,cAAc,CAACwC,SAAS,EAAE3E,MAAM,EAAEmJ,OAAO,CAAC;QAC1C;MACF;MAEA,IAAIjK,UAAU;MAEd,IAAI;QACFA,UAAU,GAAG5C,KAAK,CAAC4M,sBAAsB,CAAC;MAC5C,CAAC,CAAC,OAAO1G,GAAG,EAAE;QACZ,MAAM2G,OAAO,GAAG,yCAAyC;QACzDhH,cAAc,CAACwC,SAAS,EAAE3E,MAAM,EAAEmJ,OAAO,CAAC;QAC1C;MACF;MAEA,MAAMC,cAAc,GAAGjK,MAAM,CAACC,IAAI,CAACF,UAAU,CAAC;MAE9C,IACEkK,cAAc,CAACpK,MAAM,KAAK,CAAC,IAC3BoK,cAAc,CAAC,CAAC,CAAC,KAAK9N,iBAAiB,CAACsG,aAAa,EACrD;QACA,MAAMuH,OAAO,GAAG,sDAAsD;QACtEhH,cAAc,CAACwC,SAAS,EAAE3E,MAAM,EAAEmJ,OAAO,CAAC;QAC1C;MACF;MAEA,IAAI;QACFtE,iBAAiB,CAACwE,MAAM,CAACnK,UAAU,CAAC5D,iBAAiB,CAACsG,aAAa,CAAC,CAAC;MACvE,CAAC,CAAC,OAAOY,GAAG,EAAE;QACZ,MAAM2G,OAAO,GAAG,yCAAyC;QACzDhH,cAAc,CAACwC,SAAS,EAAE3E,MAAM,EAAEmJ,OAAO,CAAC;QAC1C;MACF;MAEAxE,SAAS,CAACjH,WAAW,CAACpC,iBAAiB,CAACsG,aAAa,CAAC,GACpDiD,iBAAiB;IACrB;IAEAF,SAAS,CAAC5E,SAAS,CAACC,MAAM,EAAEC,IAAI,EAAE;MAChCE,sBAAsB,EAAEkD,IAAI,CAAClD,sBAAsB;MACnDK,YAAY,EAAE6C,IAAI,CAAC7C,YAAY;MAC/BH,UAAU,EAAEgD,IAAI,CAAChD,UAAU;MAC3BC,kBAAkB,EAAE+C,IAAI,CAAC/C;IAC3B,CAAC,CAAC;EACJ,CAAC,CAAC;EAEF,IAAI+C,IAAI,CAACiG,aAAa,EAAE;IACtBjG,IAAI,CAACiG,aAAa,CAAC3B,GAAG,EAAEhD,SAAS,CAAC;EACpC,CAAC,MAAM;IACLgD,GAAG,CAACpF,GAAG,CAAC,CAAC;EACX;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASyD,iBAAiBA,CAACrB,SAAS,EAAEnC,GAAG,EAAE;EACzCmC,SAAS,CAAC9G,WAAW,GAAGf,SAAS,CAACuF,OAAO;EACzC;EACA;EACA;EACA;EACAsC,SAAS,CAAClH,aAAa,GAAG,IAAI;EAC9BkH,SAAS,CAAClD,IAAI,CAAC,OAAO,EAAEe,GAAG,CAAC;EAC5BmC,SAAS,CAACjD,SAAS,CAAC,CAAC;AACvB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS8E,UAAUA,CAACtJ,OAAO,EAAE;EAC3BA,OAAO,CAACkI,IAAI,GAAGlI,OAAO,CAAC8H,UAAU;EACjC,OAAOjK,GAAG,CAACwO,OAAO,CAACrM,OAAO,CAAC;AAC7B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASqJ,UAAUA,CAACrJ,OAAO,EAAE;EAC3BA,OAAO,CAACkI,IAAI,GAAG/G,SAAS;EAExB,IAAI,CAACnB,OAAO,CAACsM,UAAU,IAAItM,OAAO,CAACsM,UAAU,KAAK,EAAE,EAAE;IACpDtM,OAAO,CAACsM,UAAU,GAAGzO,GAAG,CAAC0O,IAAI,CAACvM,OAAO,CAACiI,IAAI,CAAC,GAAG,EAAE,GAAGjI,OAAO,CAACiI,IAAI;EACjE;EAEA,OAAOnK,GAAG,CAACuO,OAAO,CAACrM,OAAO,CAAC;AAC7B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASiF,cAAcA,CAACwC,SAAS,EAAE+E,MAAM,EAAEP,OAAO,EAAE;EAClDxE,SAAS,CAAC9G,WAAW,GAAGf,SAAS,CAACuF,OAAO;EAEzC,MAAMG,GAAG,GAAG,IAAIM,KAAK,CAACqG,OAAO,CAAC;EAC9BrG,KAAK,CAAC6G,iBAAiB,CAACnH,GAAG,EAAEL,cAAc,CAAC;EAE5C,IAAIuH,MAAM,CAACE,SAAS,EAAE;IACpBF,MAAM,CAACjN,QAAQ,CAAC,GAAG,IAAI;IACvBiN,MAAM,CAAChB,KAAK,CAAC,CAAC;IAEd,IAAIgB,MAAM,CAAC1J,MAAM,IAAI,CAAC0J,MAAM,CAAC1J,MAAM,CAAC6J,SAAS,EAAE;MAC7C;MACA;MACA;MACA;MACA;MACAH,MAAM,CAAC1J,MAAM,CAAC0D,OAAO,CAAC,CAAC;IACzB;IAEAoG,OAAO,CAACC,QAAQ,CAAC/D,iBAAiB,EAAErB,SAAS,EAAEnC,GAAG,CAAC;EACrD,CAAC,MAAM;IACLkH,MAAM,CAAChG,OAAO,CAAClB,GAAG,CAAC;IACnBkH,MAAM,CAACM,IAAI,CAAC,OAAO,EAAErF,SAAS,CAAClD,IAAI,CAACwI,IAAI,CAACtF,SAAS,EAAE,OAAO,CAAC,CAAC;IAC7D+E,MAAM,CAACM,IAAI,CAAC,OAAO,EAAErF,SAAS,CAACjD,SAAS,CAACuI,IAAI,CAACtF,SAAS,CAAC,CAAC;EAC3D;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS3B,cAAcA,CAAC2B,SAAS,EAAE1C,IAAI,EAAEY,EAAE,EAAE;EAC3C,IAAIZ,IAAI,EAAE;IACR,MAAMjD,MAAM,GAAGvD,MAAM,CAACwG,IAAI,CAAC,GAAGA,IAAI,CAACgH,IAAI,GAAG1M,QAAQ,CAAC0F,IAAI,CAAC,CAACjD,MAAM;;IAE/D;IACA;IACA;IACA;IACA;IACA;IACA,IAAI2F,SAAS,CAAC1G,OAAO,EAAE0G,SAAS,CAAC3G,OAAO,CAACiB,cAAc,IAAID,MAAM,CAAC,KAC7D2F,SAAS,CAACzG,eAAe,IAAIc,MAAM;EAC1C;EAEA,IAAI6D,EAAE,EAAE;IACN,MAAML,GAAG,GAAG,IAAIM,KAAK,CACnB,qCAAqC6B,SAAS,CAAC/E,UAAU,GAAG,GAC1D,IAAIhD,WAAW,CAAC+H,SAAS,CAAC/E,UAAU,CAAC,GACzC,CAAC;IACDkK,OAAO,CAACC,QAAQ,CAAClH,EAAE,EAAEL,GAAG,CAAC;EAC3B;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS9B,kBAAkBA,CAACsB,IAAI,EAAEkI,MAAM,EAAE;EACxC,MAAMvF,SAAS,GAAG,IAAI,CAAC3I,UAAU,CAAC;EAElC2I,SAAS,CAACtH,mBAAmB,GAAG,IAAI;EACpCsH,SAAS,CAACpH,aAAa,GAAG2M,MAAM;EAChCvF,SAAS,CAACvH,UAAU,GAAG4E,IAAI;EAE3B,IAAI2C,SAAS,CAAC1G,OAAO,CAACjC,UAAU,CAAC,KAAKqC,SAAS,EAAE;EAEjDsG,SAAS,CAAC1G,OAAO,CAACuG,cAAc,CAAC,MAAM,EAAEnD,YAAY,CAAC;EACtDyI,OAAO,CAACC,QAAQ,CAAC7G,MAAM,EAAEyB,SAAS,CAAC1G,OAAO,CAAC;EAE3C,IAAI+D,IAAI,KAAK,IAAI,EAAE2C,SAAS,CAAC5C,KAAK,CAAC,CAAC,CAAC,KAChC4C,SAAS,CAAC5C,KAAK,CAACC,IAAI,EAAEkI,MAAM,CAAC;AACpC;;AAEA;AACA;AACA;AACA;AACA;AACA,SAASvJ,eAAeA,CAAA,EAAG;EACzB,MAAMgE,SAAS,GAAG,IAAI,CAAC3I,UAAU,CAAC;EAElC,IAAI,CAAC2I,SAAS,CAACrF,QAAQ,EAAEqF,SAAS,CAAC1G,OAAO,CAACiF,MAAM,CAAC,CAAC;AACrD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAStC,eAAeA,CAAC4B,GAAG,EAAE;EAC5B,MAAMmC,SAAS,GAAG,IAAI,CAAC3I,UAAU,CAAC;EAElC,IAAI2I,SAAS,CAAC1G,OAAO,CAACjC,UAAU,CAAC,KAAKqC,SAAS,EAAE;IAC/CsG,SAAS,CAAC1G,OAAO,CAACuG,cAAc,CAAC,MAAM,EAAEnD,YAAY,CAAC;;IAEtD;IACA;IACA;IACA;IACAyI,OAAO,CAACC,QAAQ,CAAC7G,MAAM,EAAEyB,SAAS,CAAC1G,OAAO,CAAC;IAE3C0G,SAAS,CAAC5C,KAAK,CAACS,GAAG,CAACzG,WAAW,CAAC,CAAC;EACnC;EAEA,IAAI,CAAC4I,SAAS,CAAClH,aAAa,EAAE;IAC5BkH,SAAS,CAAClH,aAAa,GAAG,IAAI;IAC9BkH,SAAS,CAAClD,IAAI,CAAC,OAAO,EAAEe,GAAG,CAAC;EAC9B;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS2H,gBAAgBA,CAAA,EAAG;EAC1B,IAAI,CAACnO,UAAU,CAAC,CAAC0F,SAAS,CAAC,CAAC;AAC9B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASb,iBAAiBA,CAACoB,IAAI,EAAEmI,QAAQ,EAAE;EACzC,IAAI,CAACpO,UAAU,CAAC,CAACyF,IAAI,CAAC,SAAS,EAAEQ,IAAI,EAAEmI,QAAQ,CAAC;AAClD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAStJ,cAAcA,CAACmB,IAAI,EAAE;EAC5B,MAAM0C,SAAS,GAAG,IAAI,CAAC3I,UAAU,CAAC;EAElC,IAAI2I,SAAS,CAAClG,SAAS,EAAEkG,SAAS,CAAC1B,IAAI,CAAChB,IAAI,EAAE,CAAC,IAAI,CAAC9D,SAAS,EAAElC,IAAI,CAAC;EACpE0I,SAAS,CAAClD,IAAI,CAAC,MAAM,EAAEQ,IAAI,CAAC;AAC9B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAASlB,cAAcA,CAACkB,IAAI,EAAE;EAC5B,IAAI,CAACjG,UAAU,CAAC,CAACyF,IAAI,CAAC,MAAM,EAAEQ,IAAI,CAAC;AACrC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAASiB,MAAMA,CAACwG,MAAM,EAAE;EACtBA,MAAM,CAACxG,MAAM,CAAC,CAAC;AACjB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAASlC,aAAaA,CAACwB,GAAG,EAAE;EAC1B,MAAMmC,SAAS,GAAG,IAAI,CAAC3I,UAAU,CAAC;EAElC,IAAI2I,SAAS,CAAC/E,UAAU,KAAK9C,SAAS,CAAC6E,MAAM,EAAE;EAC/C,IAAIgD,SAAS,CAAC/E,UAAU,KAAK9C,SAAS,CAAC0E,IAAI,EAAE;IAC3CmD,SAAS,CAAC9G,WAAW,GAAGf,SAAS,CAACuF,OAAO;IACzCI,aAAa,CAACkC,SAAS,CAAC;EAC1B;;EAEA;EACA;EACA;EACA;EACA;EACA,IAAI,CAAC1G,OAAO,CAACsE,GAAG,CAAC,CAAC;EAElB,IAAI,CAACoC,SAAS,CAAClH,aAAa,EAAE;IAC5BkH,SAAS,CAAClH,aAAa,GAAG,IAAI;IAC9BkH,SAAS,CAAClD,IAAI,CAAC,OAAO,EAAEe,GAAG,CAAC;EAC9B;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAASC,aAAaA,CAACkC,SAAS,EAAE;EAChCA,SAAS,CAACnH,WAAW,GAAGyD,UAAU,CAChC0D,SAAS,CAAC1G,OAAO,CAACyF,OAAO,CAACuG,IAAI,CAACtF,SAAS,CAAC1G,OAAO,CAAC,EACjDzB,YACF,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS4E,aAAaA,CAAA,EAAG;EACvB,MAAMuD,SAAS,GAAG,IAAI,CAAC3I,UAAU,CAAC;EAElC,IAAI,CAACwI,cAAc,CAAC,OAAO,EAAEpD,aAAa,CAAC;EAC3C,IAAI,CAACoD,cAAc,CAAC,MAAM,EAAEnD,YAAY,CAAC;EACzC,IAAI,CAACmD,cAAc,CAAC,KAAK,EAAElD,WAAW,CAAC;EAEvCqD,SAAS,CAAC9G,WAAW,GAAGf,SAAS,CAACuF,OAAO;EAEzC,IAAIgI,KAAK;;EAET;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IACE,CAAC,IAAI,CAACC,cAAc,CAACC,UAAU,IAC/B,CAAC5F,SAAS,CAACtH,mBAAmB,IAC9B,CAACsH,SAAS,CAAC5G,SAAS,CAACgB,cAAc,CAACuD,YAAY,IAChD,CAAC+H,KAAK,GAAG1F,SAAS,CAAC1G,OAAO,CAACuM,IAAI,CAAC,CAAC,MAAM,IAAI,EAC3C;IACA7F,SAAS,CAAC5G,SAAS,CAAC0M,KAAK,CAACJ,KAAK,CAAC;EAClC;EAEA1F,SAAS,CAAC5G,SAAS,CAACwE,GAAG,CAAC,CAAC;EAEzB,IAAI,CAACvG,UAAU,CAAC,GAAGqC,SAAS;EAE5BqM,YAAY,CAAC/F,SAAS,CAACnH,WAAW,CAAC;EAEnC,IACEmH,SAAS,CAAC5G,SAAS,CAACgB,cAAc,CAAC4L,QAAQ,IAC3ChG,SAAS,CAAC5G,SAAS,CAACgB,cAAc,CAACuD,YAAY,EAC/C;IACAqC,SAAS,CAACjD,SAAS,CAAC,CAAC;EACvB,CAAC,MAAM;IACLiD,SAAS,CAAC5G,SAAS,CAAC0C,EAAE,CAAC,OAAO,EAAE0J,gBAAgB,CAAC;IACjDxF,SAAS,CAAC5G,SAAS,CAAC0C,EAAE,CAAC,QAAQ,EAAE0J,gBAAgB,CAAC;EACpD;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS9I,YAAYA,CAACgJ,KAAK,EAAE;EAC3B,IAAI,CAAC,IAAI,CAACrO,UAAU,CAAC,CAAC+B,SAAS,CAAC0M,KAAK,CAACJ,KAAK,CAAC,EAAE;IAC5C,IAAI,CAAC3H,KAAK,CAAC,CAAC;EACd;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA,SAASpB,WAAWA,CAAA,EAAG;EACrB,MAAMqD,SAAS,GAAG,IAAI,CAAC3I,UAAU,CAAC;EAElC2I,SAAS,CAAC9G,WAAW,GAAGf,SAAS,CAACuF,OAAO;EACzCsC,SAAS,CAAC5G,SAAS,CAACwE,GAAG,CAAC,CAAC;EACzB,IAAI,CAACA,GAAG,CAAC,CAAC;AACZ;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAShB,aAAaA,CAAA,EAAG;EACvB,MAAMoD,SAAS,GAAG,IAAI,CAAC3I,UAAU,CAAC;EAElC,IAAI,CAACwI,cAAc,CAAC,OAAO,EAAEjD,aAAa,CAAC;EAC3C,IAAI,CAACd,EAAE,CAAC,OAAO,EAAExE,IAAI,CAAC;EAEtB,IAAI0I,SAAS,EAAE;IACbA,SAAS,CAAC9G,WAAW,GAAGf,SAAS,CAACuF,OAAO;IACzC,IAAI,CAACqB,OAAO,CAAC,CAAC;EAChB;AACF","ignoreList":[]},"metadata":{},"sourceType":"script","externalDependencies":[]} |