randomness-js
Version:
A library for consuming, verifying and using randomness from the dcipher network
4 lines • 4.77 MB
Source Map (JSON)
{
"version": 3,
"sources": ["../../node_modules/ws/lib/stream.js", "../../node_modules/ws/lib/constants.js", "../../node_modules/ws/lib/buffer-util.js", "../../node_modules/ws/lib/limiter.js", "../../node_modules/ws/lib/permessage-deflate.js", "../../node_modules/ws/lib/validation.js", "../../node_modules/ws/lib/receiver.js", "../../node_modules/ws/lib/sender.js", "../../node_modules/ws/lib/event-target.js", "../../node_modules/ws/lib/extension.js", "../../node_modules/ws/lib/websocket.js", "../../node_modules/ws/lib/subprotocol.js", "../../node_modules/ws/lib/websocket-server.js", "../../node_modules/@noble/hashes/src/cryptoNode.ts", "../../node_modules/@noble/hashes/src/utils.ts", "../../node_modules/@noble/curves/src/abstract/utils.ts", "../../node_modules/@noble/curves/src/abstract/modular.ts", "../../node_modules/@noble/curves/src/abstract/hash-to-curve.ts", "../../node_modules/@noble/curves/src/abstract/curve.ts", "../../node_modules/@noble/curves/src/abstract/weierstrass.ts", "../../node_modules/@noble/curves/src/abstract/bls.ts", "../../node_modules/@noble/curves/src/abstract/tower.ts", "../../node_modules/@noble/hashes/src/_assert.ts", "../../node_modules/@noble/hashes/src/_u64.ts", "../../node_modules/@noble/hashes/src/sha3.ts", "../../node_modules/@kevincharm/noble-bn254-drand/dist/src/bn254.js", "../../node_modules/@kevincharm/noble-bn254-drand/dist/src/index.js", "../../src/index.ts", "../../node_modules/ethers/src.ts/ethers.ts", "../../node_modules/ethers/src.ts/_version.ts", "../../node_modules/ethers/src.ts/utils/properties.ts", "../../node_modules/ethers/src.ts/utils/errors.ts", "../../node_modules/ethers/src.ts/utils/data.ts", "../../node_modules/ethers/src.ts/utils/maths.ts", "../../node_modules/ethers/src.ts/utils/base58.ts", "../../node_modules/ethers/src.ts/utils/base64.ts", "../../node_modules/ethers/src.ts/utils/events.ts", "../../node_modules/ethers/src.ts/utils/utf8.ts", "../../node_modules/ethers/src.ts/utils/geturl.ts", "../../node_modules/ethers/src.ts/utils/fetch.ts", "../../node_modules/ethers/src.ts/utils/fixednumber.ts", "../../node_modules/ethers/src.ts/utils/rlp-decode.ts", "../../node_modules/ethers/src.ts/utils/rlp-encode.ts", "../../node_modules/ethers/src.ts/utils/units.ts", "../../node_modules/ethers/src.ts/utils/uuid.ts", "../../node_modules/ethers/src.ts/abi/coders/abstract-coder.ts", "../../node_modules/ethers/src.ts/crypto/crypto.ts", "../../node_modules/ethers/src.ts/crypto/hmac.ts", "../../node_modules/@noble/hashes/src/_assert.ts", "../../node_modules/@noble/hashes/src/_u64.ts", "../../node_modules/@noble/hashes/src/cryptoNode.ts", "../../node_modules/@noble/hashes/src/utils.ts", "../../node_modules/@noble/hashes/src/sha3.ts", "../../node_modules/ethers/src.ts/crypto/keccak.ts", "../../node_modules/@noble/hashes/src/_sha2.ts", "../../node_modules/@noble/hashes/src/ripemd160.ts", "../../node_modules/ethers/src.ts/crypto/ripemd160.ts", "../../node_modules/ethers/src.ts/crypto/pbkdf2.ts", "../../node_modules/ethers/src.ts/crypto/random.ts", "../../node_modules/@noble/hashes/src/sha256.ts", "../../node_modules/@noble/hashes/src/hmac.ts", "../../node_modules/@noble/hashes/src/pbkdf2.ts", "../../node_modules/@noble/hashes/src/scrypt.ts", "../../node_modules/ethers/src.ts/crypto/scrypt.ts", "../../node_modules/ethers/src.ts/crypto/sha2.ts", "../../node_modules/ethers/node_modules/@noble/curves/src/abstract/utils.ts", "../../node_modules/ethers/node_modules/@noble/curves/src/abstract/modular.ts", "../../node_modules/ethers/node_modules/@noble/curves/src/abstract/curve.ts", "../../node_modules/ethers/node_modules/@noble/curves/src/abstract/weierstrass.ts", "../../node_modules/ethers/node_modules/@noble/curves/src/_shortw_utils.ts", "../../node_modules/ethers/node_modules/@noble/curves/src/secp256k1.ts", "../../node_modules/ethers/src.ts/constants/addresses.ts", "../../node_modules/ethers/src.ts/constants/hashes.ts", "../../node_modules/ethers/src.ts/constants/numbers.ts", "../../node_modules/ethers/src.ts/constants/strings.ts", "../../node_modules/ethers/src.ts/crypto/signature.ts", "../../node_modules/ethers/src.ts/crypto/signing-key.ts", "../../node_modules/ethers/src.ts/crypto/index.ts", "../../node_modules/ethers/src.ts/address/address.ts", "../../node_modules/ethers/src.ts/address/contract-address.ts", "../../node_modules/ethers/src.ts/address/checks.ts", "../../node_modules/ethers/src.ts/abi/typed.ts", "../../node_modules/ethers/src.ts/abi/coders/address.ts", "../../node_modules/ethers/src.ts/abi/coders/anonymous.ts", "../../node_modules/ethers/src.ts/abi/coders/array.ts", "../../node_modules/ethers/src.ts/abi/coders/boolean.ts", "../../node_modules/ethers/src.ts/abi/coders/bytes.ts", "../../node_modules/ethers/src.ts/abi/coders/fixed-bytes.ts", "../../node_modules/ethers/src.ts/abi/coders/null.ts", "../../node_modules/ethers/src.ts/abi/coders/number.ts", "../../node_modules/ethers/src.ts/abi/coders/string.ts", "../../node_modules/ethers/src.ts/abi/coders/tuple.ts", "../../node_modules/ethers/src.ts/hash/id.ts", "../../node_modules/@adraffy/ens-normalize/dist/index.mjs", "../../node_modules/ethers/src.ts/hash/namehash.ts", "../../node_modules/ethers/src.ts/transaction/accesslist.ts", "../../node_modules/ethers/src.ts/transaction/address.ts", "../../node_modules/ethers/src.ts/transaction/transaction.ts", "../../node_modules/ethers/src.ts/hash/message.ts", "../../node_modules/ethers/src.ts/hash/solidity.ts", "../../node_modules/ethers/src.ts/hash/typed-data.ts", "../../node_modules/ethers/src.ts/abi/fragments.ts", "../../node_modules/ethers/src.ts/abi/abi-coder.ts", "../../node_modules/ethers/src.ts/abi/bytes32.ts", "../../node_modules/ethers/src.ts/abi/interface.ts", "../../node_modules/ethers/src.ts/providers/provider.ts", "../../node_modules/ethers/src.ts/contract/wrappers.ts", "../../node_modules/ethers/src.ts/contract/contract.ts", "../../node_modules/ethers/src.ts/contract/factory.ts", "../../node_modules/ethers/src.ts/providers/ens-resolver.ts", "../../node_modules/ethers/src.ts/providers/format.ts", "../../node_modules/ethers/src.ts/providers/plugins-network.ts", "../../node_modules/ethers/src.ts/providers/network.ts", "../../node_modules/ethers/src.ts/providers/subscriber-polling.ts", "../../node_modules/ethers/src.ts/providers/abstract-provider.ts", "../../node_modules/ethers/src.ts/providers/abstract-signer.ts", "../../node_modules/ethers/src.ts/providers/community.ts", "../../node_modules/ethers/src.ts/providers/subscriber-filterid.ts", "../../node_modules/ethers/src.ts/providers/provider-jsonrpc.ts", "../../node_modules/ethers/src.ts/providers/provider-ankr.ts", "../../node_modules/ethers/src.ts/providers/provider-alchemy.ts", "../../node_modules/ethers/src.ts/providers/provider-chainstack.ts", "../../node_modules/ethers/src.ts/providers/provider-cloudflare.ts", "../../node_modules/ethers/src.ts/providers/provider-etherscan.ts", "../../node_modules/ws/wrapper.mjs", "../../node_modules/ethers/src.ts/providers/provider-socket.ts", "../../node_modules/ethers/src.ts/providers/provider-websocket.ts", "../../node_modules/ethers/src.ts/providers/provider-infura.ts", "../../node_modules/ethers/src.ts/providers/provider-quicknode.ts", "../../node_modules/ethers/src.ts/providers/provider-fallback.ts", "../../node_modules/ethers/src.ts/providers/default-provider.ts", "../../node_modules/ethers/src.ts/providers/signer-noncemanager.ts", "../../node_modules/ethers/src.ts/providers/provider-browser.ts", "../../node_modules/ethers/src.ts/providers/provider-pocket.ts", "../../node_modules/ethers/src.ts/providers/provider-ipcsocket.ts", "../../node_modules/ethers/src.ts/wallet/base-wallet.ts", "../../node_modules/ethers/src.ts/wordlists/decode-owl.ts", "../../node_modules/ethers/src.ts/wordlists/wordlist.ts", "../../node_modules/ethers/src.ts/wordlists/wordlist-owl.ts", "../../node_modules/ethers/src.ts/wordlists/lang-en.ts", "../../node_modules/ethers/src.ts/wallet/mnemonic.ts", "../../node_modules/aes-js/src.ts/aes.ts", "../../node_modules/aes-js/src.ts/mode.ts", "../../node_modules/aes-js/src.ts/mode-cbc.ts", "../../node_modules/aes-js/src.ts/mode-ctr.ts", "../../node_modules/aes-js/src.ts/padding.ts", "../../node_modules/ethers/src.ts/wallet/utils.ts", "../../node_modules/ethers/src.ts/wallet/json-keystore.ts", "../../node_modules/ethers/src.ts/wallet/hdwallet.ts", "../../node_modules/ethers/src.ts/wallet/json-crowdsale.ts", "../../node_modules/ethers/src.ts/wallet/wallet.ts", "../../node_modules/ethers/src.ts/wordlists/bit-reader.ts", "../../node_modules/ethers/src.ts/wordlists/decode-owla.ts", "../../node_modules/ethers/src.ts/wordlists/wordlist-owla.ts", "../../node_modules/ethers/src.ts/wordlists/lang-cz.ts", "../../node_modules/ethers/src.ts/wordlists/lang-es.ts", "../../node_modules/ethers/src.ts/wordlists/lang-fr.ts", "../../node_modules/ethers/src.ts/wordlists/lang-ja.ts", "../../node_modules/ethers/src.ts/wordlists/lang-ko.ts", "../../node_modules/ethers/src.ts/wordlists/lang-it.ts", "../../node_modules/ethers/src.ts/wordlists/lang-pt.ts", "../../node_modules/ethers/src.ts/wordlists/lang-zh.ts", "../../node_modules/ethers/src.ts/wordlists/wordlists.ts", "../../node_modules/@noble/curves/src/abstract/utils.ts", "../../src/ethers-helpers.ts", "../../src/generated/factories/Base.t.sol/Base__factory.ts", "../../src/generated/factories/ChainlinkVRFV2_5Integration_DirectFunding.t.sol/ChainlinkVRFV2_5Integration_DirectFundingTest__factory.ts", "../../src/generated/factories/ChainlinkVRFV2_5Integration_Subscription.t.sol/ChainlinkVRFV2_5Integration_SubscriptionTest__factory.ts", "../../src/generated/factories/Deployment.t.sol/Deployment__factory.ts", "../../src/generated/factories/DirectFunding.t.sol/DirectFundingTest__factory.ts", "../../src/generated/factories/Randomness.t.sol/RandomnessTest__factory.ts", "../../src/generated/factories/StdError.sol/StdError__factory.ts", "../../src/generated/factories/StdStorage.sol/StdStorageSafe__factory.ts", "../../src/generated/factories/SubscriptionFunding.t.sol/SubscriptionFundingTest__factory.ts", "../../src/generated/factories/Vm.sol/Vm__factory.ts", "../../src/generated/factories/Vm.sol/VmSafe__factory.ts", "../../src/generated/factories/draft-IERC1822.sol/IERC1822Proxiable__factory.ts", "../../src/generated/factories/AccessControl__factory.ts", "../../src/generated/factories/AccessControlEnumerableUpgradeable__factory.ts", "../../src/generated/factories/AccessControlUpgradeable__factory.ts", "../../src/generated/factories/Address__factory.ts", "../../src/generated/factories/BLS__factory.ts", "../../src/generated/factories/BLSTest__factory.ts", "../../src/generated/factories/BN254SignatureScheme__factory.ts", "../../src/generated/factories/BytesLib__factory.ts", "../../src/generated/factories/ChainlinkVRFCoordinatorV2_5Adapter__factory.ts", "../../src/generated/factories/ChainlinkVRFDirectFundingConsumer__factory.ts", "../../src/generated/factories/ChainlinkVRFSubscriptionConsumer__factory.ts", "../../src/generated/factories/ChainlinkVRFV2PlusWrapperAdapter__factory.ts", "../../src/generated/factories/ChainlinkVRFV2PlusWrapperConsumerBaseStub__factory.ts", "../../src/generated/factories/ConfirmedOwner__factory.ts", "../../src/generated/factories/ConfirmedOwnerWithProposal__factory.ts", "../../src/generated/factories/ContextUpgradeable__factory.ts", "../../src/generated/factories/ERC165__factory.ts", "../../src/generated/factories/ERC165Upgradeable__factory.ts", "../../src/generated/factories/ERC1967Proxy__factory.ts", "../../src/generated/factories/ERC1967Utils__factory.ts", "../../src/generated/factories/Errors__factory.ts", "../../src/generated/factories/Factory__factory.ts", "../../src/generated/factories/FeeCollector__factory.ts", "../../src/generated/factories/FeistelShuffleOptimised__factory.ts", "../../src/generated/factories/IAccessControl__factory.ts", "../../src/generated/factories/IAccessControlEnumerable__factory.ts", "../../src/generated/factories/IBeacon__factory.ts", "../../src/generated/factories/IERC165__factory.ts", "../../src/generated/factories/IERC1967__factory.ts", "../../src/generated/factories/IMulticall3__factory.ts", "../../src/generated/factories/IOwnable__factory.ts", "../../src/generated/factories/IRandomnessReceiver__factory.ts", "../../src/generated/factories/IRandomnessSender__factory.ts", "../../src/generated/factories/ISignatureReceiver__factory.ts", "../../src/generated/factories/ISignatureScheme__factory.ts", "../../src/generated/factories/ISignatureSchemeAddressProvider__factory.ts", "../../src/generated/factories/ISignatureSender__factory.ts", "../../src/generated/factories/ISubscription__factory.ts", "../../src/generated/factories/ITypeAndVersion__factory.ts", "../../src/generated/factories/IVRFCoordinatorV2Plus__factory.ts", "../../src/generated/factories/IVRFMigratableConsumerV2Plus__factory.ts", "../../src/generated/factories/IVRFSubscriptionV2Plus__factory.ts", "../../src/generated/factories/IVRFV2PlusWrapper__factory.ts", "../../src/generated/factories/Initializable__factory.ts", "../../src/generated/factories/LinkTokenInterface__factory.ts", "../../src/generated/factories/MockRandomnessReceiver__factory.ts", "../../src/generated/factories/MockRevertingRandomnessReceiver__factory.ts", "../../src/generated/factories/Multicall__factory.ts", "../../src/generated/factories/Proxy__factory.ts", "../../src/generated/factories/Randomness__factory.ts", "../../src/generated/factories/RandomnessReceiverBase__factory.ts", "../../src/generated/factories/RandomnessSender__factory.ts", "../../src/generated/factories/ReentrancyGuard__factory.ts", "../../src/generated/factories/SignatureReceiverBase__factory.ts", "../../src/generated/factories/SignatureSchemeAddressProvider__factory.ts", "../../src/generated/factories/SignatureSchemeBase__factory.ts", "../../src/generated/factories/SignatureSender__factory.ts", "../../src/generated/factories/StdAssertions__factory.ts", "../../src/generated/factories/StdInvariant__factory.ts", "../../src/generated/factories/SubscriptionAPI__factory.ts", "../../src/generated/factories/Test__factory.ts", "../../src/generated/factories/UUPSProxy__factory.ts", "../../src/generated/factories/UUPSUpgradeable__factory.ts", "../../src/generated/factories/VRFConsumerBaseV2Plus__factory.ts", "../../src/generated/factories/VRFV2PlusClient__factory.ts", "../../src/generated/factories/VRFV2PlusWrapperConsumerBase__factory.ts", "../../src/networks.ts"],
"sourcesContent": ["'use strict';\n\nconst { Duplex } = require('stream');\n\n/**\n * Emits the `'close'` event on a stream.\n *\n * @param {Duplex} stream The stream.\n * @private\n */\nfunction emitClose(stream) {\n stream.emit('close');\n}\n\n/**\n * The listener of the `'end'` event.\n *\n * @private\n */\nfunction duplexOnEnd() {\n if (!this.destroyed && this._writableState.finished) {\n this.destroy();\n }\n}\n\n/**\n * The listener of the `'error'` event.\n *\n * @param {Error} err The error\n * @private\n */\nfunction duplexOnError(err) {\n this.removeListener('error', duplexOnError);\n this.destroy();\n if (this.listenerCount('error') === 0) {\n // Do not suppress the throwing behavior.\n this.emit('error', err);\n }\n}\n\n/**\n * Wraps a `WebSocket` in a duplex stream.\n *\n * @param {WebSocket} ws The `WebSocket` to wrap\n * @param {Object} [options] The options for the `Duplex` constructor\n * @return {Duplex} The duplex stream\n * @public\n */\nfunction createWebSocketStream(ws, options) {\n let terminateOnDestroy = true;\n\n const duplex = new Duplex({\n ...options,\n autoDestroy: false,\n emitClose: false,\n objectMode: false,\n writableObjectMode: false\n });\n\n ws.on('message', function message(msg, isBinary) {\n const data =\n !isBinary && duplex._readableState.objectMode ? msg.toString() : msg;\n\n if (!duplex.push(data)) ws.pause();\n });\n\n ws.once('error', function error(err) {\n if (duplex.destroyed) return;\n\n // Prevent `ws.terminate()` from being called by `duplex._destroy()`.\n //\n // - If the `'error'` event is emitted before the `'open'` event, then\n // `ws.terminate()` is a noop as no socket is assigned.\n // - Otherwise, the error is re-emitted by the listener of the `'error'`\n // event of the `Receiver` object. The listener already closes the\n // connection by calling `ws.close()`. This allows a close frame to be\n // sent to the other peer. If `ws.terminate()` is called right after this,\n // then the close frame might not be sent.\n terminateOnDestroy = false;\n duplex.destroy(err);\n });\n\n ws.once('close', function close() {\n if (duplex.destroyed) return;\n\n duplex.push(null);\n });\n\n duplex._destroy = function (err, callback) {\n if (ws.readyState === ws.CLOSED) {\n callback(err);\n process.nextTick(emitClose, duplex);\n return;\n }\n\n let called = false;\n\n ws.once('error', function error(err) {\n called = true;\n callback(err);\n });\n\n ws.once('close', function close() {\n if (!called) callback(err);\n process.nextTick(emitClose, duplex);\n });\n\n if (terminateOnDestroy) ws.terminate();\n };\n\n duplex._final = function (callback) {\n if (ws.readyState === ws.CONNECTING) {\n ws.once('open', function open() {\n duplex._final(callback);\n });\n return;\n }\n\n // If the value of the `_socket` property is `null` it means that `ws` is a\n // client websocket and the handshake failed. In fact, when this happens, a\n // socket is never assigned to the websocket. Wait for the `'error'` event\n // that will be emitted by the websocket.\n if (ws._socket === null) return;\n\n if (ws._socket._writableState.finished) {\n callback();\n if (duplex._readableState.endEmitted) duplex.destroy();\n } else {\n ws._socket.once('finish', function finish() {\n // `duplex` is not destroyed here because the `'end'` event will be\n // emitted on `duplex` after this `'finish'` event. The EOF signaling\n // `null` chunk is, in fact, pushed when the websocket emits `'close'`.\n callback();\n });\n ws.close();\n }\n };\n\n duplex._read = function () {\n if (ws.isPaused) ws.resume();\n };\n\n duplex._write = function (chunk, encoding, callback) {\n if (ws.readyState === ws.CONNECTING) {\n ws.once('open', function open() {\n duplex._write(chunk, encoding, callback);\n });\n return;\n }\n\n ws.send(chunk, callback);\n };\n\n duplex.on('end', duplexOnEnd);\n duplex.on('error', duplexOnError);\n return duplex;\n}\n\nmodule.exports = createWebSocketStream;\n", "'use strict';\n\nmodule.exports = {\n BINARY_TYPES: ['nodebuffer', 'arraybuffer', 'fragments'],\n EMPTY_BUFFER: Buffer.alloc(0),\n GUID: '258EAFA5-E914-47DA-95CA-C5AB0DC85B11',\n kForOnEventAttribute: Symbol('kIsForOnEventAttribute'),\n kListener: Symbol('kListener'),\n kStatusCode: Symbol('status-code'),\n kWebSocket: Symbol('websocket'),\n NOOP: () => {}\n};\n", "'use strict';\n\nconst { EMPTY_BUFFER } = require('./constants');\n\nconst FastBuffer = Buffer[Symbol.species];\n\n/**\n * Merges an array of buffers into a new buffer.\n *\n * @param {Buffer[]} list The array of buffers to concat\n * @param {Number} totalLength The total length of buffers in the list\n * @return {Buffer} The resulting buffer\n * @public\n */\nfunction concat(list, totalLength) {\n if (list.length === 0) return EMPTY_BUFFER;\n if (list.length === 1) return list[0];\n\n const target = Buffer.allocUnsafe(totalLength);\n let offset = 0;\n\n for (let i = 0; i < list.length; i++) {\n const buf = list[i];\n target.set(buf, offset);\n offset += buf.length;\n }\n\n if (offset < totalLength) {\n return new FastBuffer(target.buffer, target.byteOffset, offset);\n }\n\n return target;\n}\n\n/**\n * Masks a buffer using the given mask.\n *\n * @param {Buffer} source The buffer to mask\n * @param {Buffer} mask The mask to use\n * @param {Buffer} output The buffer where to store the result\n * @param {Number} offset The offset at which to start writing\n * @param {Number} length The number of bytes to mask.\n * @public\n */\nfunction _mask(source, mask, output, offset, length) {\n for (let i = 0; i < length; i++) {\n output[offset + i] = source[i] ^ mask[i & 3];\n }\n}\n\n/**\n * Unmasks a buffer using the given mask.\n *\n * @param {Buffer} buffer The buffer to unmask\n * @param {Buffer} mask The mask to use\n * @public\n */\nfunction _unmask(buffer, mask) {\n for (let i = 0; i < buffer.length; i++) {\n buffer[i] ^= mask[i & 3];\n }\n}\n\n/**\n * Converts a buffer to an `ArrayBuffer`.\n *\n * @param {Buffer} buf The buffer to convert\n * @return {ArrayBuffer} Converted buffer\n * @public\n */\nfunction toArrayBuffer(buf) {\n if (buf.length === buf.buffer.byteLength) {\n return buf.buffer;\n }\n\n return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.length);\n}\n\n/**\n * Converts `data` to a `Buffer`.\n *\n * @param {*} data The data to convert\n * @return {Buffer} The buffer\n * @throws {TypeError}\n * @public\n */\nfunction toBuffer(data) {\n toBuffer.readOnly = true;\n\n if (Buffer.isBuffer(data)) return data;\n\n let buf;\n\n if (data instanceof ArrayBuffer) {\n buf = new FastBuffer(data);\n } else if (ArrayBuffer.isView(data)) {\n buf = new FastBuffer(data.buffer, data.byteOffset, data.byteLength);\n } else {\n buf = Buffer.from(data);\n toBuffer.readOnly = false;\n }\n\n return buf;\n}\n\nmodule.exports = {\n concat,\n mask: _mask,\n toArrayBuffer,\n toBuffer,\n unmask: _unmask\n};\n\n/* istanbul ignore else */\nif (!process.env.WS_NO_BUFFER_UTIL) {\n try {\n const bufferUtil = require('bufferutil');\n\n module.exports.mask = function (source, mask, output, offset, length) {\n if (length < 48) _mask(source, mask, output, offset, length);\n else bufferUtil.mask(source, mask, output, offset, length);\n };\n\n module.exports.unmask = function (buffer, mask) {\n if (buffer.length < 32) _unmask(buffer, mask);\n else bufferUtil.unmask(buffer, mask);\n };\n } catch (e) {\n // Continue regardless of the error.\n }\n}\n", "'use strict';\n\nconst kDone = Symbol('kDone');\nconst kRun = Symbol('kRun');\n\n/**\n * A very simple job queue with adjustable concurrency. Adapted from\n * https://github.com/STRML/async-limiter\n */\nclass Limiter {\n /**\n * Creates a new `Limiter`.\n *\n * @param {Number} [concurrency=Infinity] The maximum number of jobs allowed\n * to run concurrently\n */\n constructor(concurrency) {\n this[kDone] = () => {\n this.pending--;\n this[kRun]();\n };\n this.concurrency = concurrency || Infinity;\n this.jobs = [];\n this.pending = 0;\n }\n\n /**\n * Adds a job to the queue.\n *\n * @param {Function} job The job to run\n * @public\n */\n add(job) {\n this.jobs.push(job);\n this[kRun]();\n }\n\n /**\n * Removes a job from the queue and runs it if possible.\n *\n * @private\n */\n [kRun]() {\n if (this.pending === this.concurrency) return;\n\n if (this.jobs.length) {\n const job = this.jobs.shift();\n\n this.pending++;\n job(this[kDone]);\n }\n }\n}\n\nmodule.exports = Limiter;\n", "'use strict';\n\nconst zlib = require('zlib');\n\nconst bufferUtil = require('./buffer-util');\nconst Limiter = require('./limiter');\nconst { kStatusCode } = require('./constants');\n\nconst FastBuffer = Buffer[Symbol.species];\nconst TRAILER = Buffer.from([0x00, 0x00, 0xff, 0xff]);\nconst kPerMessageDeflate = Symbol('permessage-deflate');\nconst kTotalLength = Symbol('total-length');\nconst kCallback = Symbol('callback');\nconst kBuffers = Symbol('buffers');\nconst kError = Symbol('error');\n\n//\n// We limit zlib concurrency, which prevents severe memory fragmentation\n// as documented in https://github.com/nodejs/node/issues/8871#issuecomment-250915913\n// and https://github.com/websockets/ws/issues/1202\n//\n// Intentionally global; it's the global thread pool that's an issue.\n//\nlet zlibLimiter;\n\n/**\n * permessage-deflate implementation.\n */\nclass PerMessageDeflate {\n /**\n * Creates a PerMessageDeflate instance.\n *\n * @param {Object} [options] Configuration options\n * @param {(Boolean|Number)} [options.clientMaxWindowBits] Advertise support\n * for, or request, a custom client window size\n * @param {Boolean} [options.clientNoContextTakeover=false] Advertise/\n * acknowledge disabling of client context takeover\n * @param {Number} [options.concurrencyLimit=10] The number of concurrent\n * calls to zlib\n * @param {(Boolean|Number)} [options.serverMaxWindowBits] Request/confirm the\n * use of a custom server window size\n * @param {Boolean} [options.serverNoContextTakeover=false] Request/accept\n * disabling of server context takeover\n * @param {Number} [options.threshold=1024] Size (in bytes) below which\n * messages should not be compressed if context takeover is disabled\n * @param {Object} [options.zlibDeflateOptions] Options to pass to zlib on\n * deflate\n * @param {Object} [options.zlibInflateOptions] Options to pass to zlib on\n * inflate\n * @param {Boolean} [isServer=false] Create the instance in either server or\n * client mode\n * @param {Number} [maxPayload=0] The maximum allowed message length\n */\n constructor(options, isServer, maxPayload) {\n this._maxPayload = maxPayload | 0;\n this._options = options || {};\n this._threshold =\n this._options.threshold !== undefined ? this._options.threshold : 1024;\n this._isServer = !!isServer;\n this._deflate = null;\n this._inflate = null;\n\n this.params = null;\n\n if (!zlibLimiter) {\n const concurrency =\n this._options.concurrencyLimit !== undefined\n ? this._options.concurrencyLimit\n : 10;\n zlibLimiter = new Limiter(concurrency);\n }\n }\n\n /**\n * @type {String}\n */\n static get extensionName() {\n return 'permessage-deflate';\n }\n\n /**\n * Create an extension negotiation offer.\n *\n * @return {Object} Extension parameters\n * @public\n */\n offer() {\n const params = {};\n\n if (this._options.serverNoContextTakeover) {\n params.server_no_context_takeover = true;\n }\n if (this._options.clientNoContextTakeover) {\n params.client_no_context_takeover = true;\n }\n if (this._options.serverMaxWindowBits) {\n params.server_max_window_bits = this._options.serverMaxWindowBits;\n }\n if (this._options.clientMaxWindowBits) {\n params.client_max_window_bits = this._options.clientMaxWindowBits;\n } else if (this._options.clientMaxWindowBits == null) {\n params.client_max_window_bits = true;\n }\n\n return params;\n }\n\n /**\n * Accept an extension negotiation offer/response.\n *\n * @param {Array} configurations The extension negotiation offers/reponse\n * @return {Object} Accepted configuration\n * @public\n */\n accept(configurations) {\n configurations = this.normalizeParams(configurations);\n\n this.params = this._isServer\n ? this.acceptAsServer(configurations)\n : this.acceptAsClient(configurations);\n\n return this.params;\n }\n\n /**\n * Releases all resources used by the extension.\n *\n * @public\n */\n cleanup() {\n if (this._inflate) {\n this._inflate.close();\n this._inflate = null;\n }\n\n if (this._deflate) {\n const callback = this._deflate[kCallback];\n\n this._deflate.close();\n this._deflate = null;\n\n if (callback) {\n callback(\n new Error(\n 'The deflate stream was closed while data was being processed'\n )\n );\n }\n }\n }\n\n /**\n * Accept an extension negotiation offer.\n *\n * @param {Array} offers The extension negotiation offers\n * @return {Object} Accepted configuration\n * @private\n */\n acceptAsServer(offers) {\n const opts = this._options;\n const accepted = offers.find((params) => {\n if (\n (opts.serverNoContextTakeover === false &&\n params.server_no_context_takeover) ||\n (params.server_max_window_bits &&\n (opts.serverMaxWindowBits === false ||\n (typeof opts.serverMaxWindowBits === 'number' &&\n opts.serverMaxWindowBits > params.server_max_window_bits))) ||\n (typeof opts.clientMaxWindowBits === 'number' &&\n !params.client_max_window_bits)\n ) {\n return false;\n }\n\n return true;\n });\n\n if (!accepted) {\n throw new Error('None of the extension offers can be accepted');\n }\n\n if (opts.serverNoContextTakeover) {\n accepted.server_no_context_takeover = true;\n }\n if (opts.clientNoContextTakeover) {\n accepted.client_no_context_takeover = true;\n }\n if (typeof opts.serverMaxWindowBits === 'number') {\n accepted.server_max_window_bits = opts.serverMaxWindowBits;\n }\n if (typeof opts.clientMaxWindowBits === 'number') {\n accepted.client_max_window_bits = opts.clientMaxWindowBits;\n } else if (\n accepted.client_max_window_bits === true ||\n opts.clientMaxWindowBits === false\n ) {\n delete accepted.client_max_window_bits;\n }\n\n return accepted;\n }\n\n /**\n * Accept the extension negotiation response.\n *\n * @param {Array} response The extension negotiation response\n * @return {Object} Accepted configuration\n * @private\n */\n acceptAsClient(response) {\n const params = response[0];\n\n if (\n this._options.clientNoContextTakeover === false &&\n params.client_no_context_takeover\n ) {\n throw new Error('Unexpected parameter \"client_no_context_takeover\"');\n }\n\n if (!params.client_max_window_bits) {\n if (typeof this._options.clientMaxWindowBits === 'number') {\n params.client_max_window_bits = this._options.clientMaxWindowBits;\n }\n } else if (\n this._options.clientMaxWindowBits === false ||\n (typeof this._options.clientMaxWindowBits === 'number' &&\n params.client_max_window_bits > this._options.clientMaxWindowBits)\n ) {\n throw new Error(\n 'Unexpected or invalid parameter \"client_max_window_bits\"'\n );\n }\n\n return params;\n }\n\n /**\n * Normalize parameters.\n *\n * @param {Array} configurations The extension negotiation offers/reponse\n * @return {Array} The offers/response with normalized parameters\n * @private\n */\n normalizeParams(configurations) {\n configurations.forEach((params) => {\n Object.keys(params).forEach((key) => {\n let value = params[key];\n\n if (value.length > 1) {\n throw new Error(`Parameter \"${key}\" must have only a single value`);\n }\n\n value = value[0];\n\n if (key === 'client_max_window_bits') {\n if (value !== true) {\n const num = +value;\n if (!Number.isInteger(num) || num < 8 || num > 15) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n value = num;\n } else if (!this._isServer) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n } else if (key === 'server_max_window_bits') {\n const num = +value;\n if (!Number.isInteger(num) || num < 8 || num > 15) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n value = num;\n } else if (\n key === 'client_no_context_takeover' ||\n key === 'server_no_context_takeover'\n ) {\n if (value !== true) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n } else {\n throw new Error(`Unknown parameter \"${key}\"`);\n }\n\n params[key] = value;\n });\n });\n\n return configurations;\n }\n\n /**\n * Decompress data. Concurrency limited.\n *\n * @param {Buffer} data Compressed data\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @public\n */\n decompress(data, fin, callback) {\n zlibLimiter.add((done) => {\n this._decompress(data, fin, (err, result) => {\n done();\n callback(err, result);\n });\n });\n }\n\n /**\n * Compress data. Concurrency limited.\n *\n * @param {(Buffer|String)} data Data to compress\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @public\n */\n compress(data, fin, callback) {\n zlibLimiter.add((done) => {\n this._compress(data, fin, (err, result) => {\n done();\n callback(err, result);\n });\n });\n }\n\n /**\n * Decompress data.\n *\n * @param {Buffer} data Compressed data\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @private\n */\n _decompress(data, fin, callback) {\n const endpoint = this._isServer ? 'client' : 'server';\n\n if (!this._inflate) {\n const key = `${endpoint}_max_window_bits`;\n const windowBits =\n typeof this.params[key] !== 'number'\n ? zlib.Z_DEFAULT_WINDOWBITS\n : this.params[key];\n\n this._inflate = zlib.createInflateRaw({\n ...this._options.zlibInflateOptions,\n windowBits\n });\n this._inflate[kPerMessageDeflate] = this;\n this._inflate[kTotalLength] = 0;\n this._inflate[kBuffers] = [];\n this._inflate.on('error', inflateOnError);\n this._inflate.on('data', inflateOnData);\n }\n\n this._inflate[kCallback] = callback;\n\n this._inflate.write(data);\n if (fin) this._inflate.write(TRAILER);\n\n this._inflate.flush(() => {\n const err = this._inflate[kError];\n\n if (err) {\n this._inflate.close();\n this._inflate = null;\n callback(err);\n return;\n }\n\n const data = bufferUtil.concat(\n this._inflate[kBuffers],\n this._inflate[kTotalLength]\n );\n\n if (this._inflate._readableState.endEmitted) {\n this._inflate.close();\n this._inflate = null;\n } else {\n this._inflate[kTotalLength] = 0;\n this._inflate[kBuffers] = [];\n\n if (fin && this.params[`${endpoint}_no_context_takeover`]) {\n this._inflate.reset();\n }\n }\n\n callback(null, data);\n });\n }\n\n /**\n * Compress data.\n *\n * @param {(Buffer|String)} data Data to compress\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @private\n */\n _compress(data, fin, callback) {\n const endpoint = this._isServer ? 'server' : 'client';\n\n if (!this._deflate) {\n const key = `${endpoint}_max_window_bits`;\n const windowBits =\n typeof this.params[key] !== 'number'\n ? zlib.Z_DEFAULT_WINDOWBITS\n : this.params[key];\n\n this._deflate = zlib.createDeflateRaw({\n ...this._options.zlibDeflateOptions,\n windowBits\n });\n\n this._deflate[kTotalLength] = 0;\n this._deflate[kBuffers] = [];\n\n this._deflate.on('data', deflateOnData);\n }\n\n this._deflate[kCallback] = callback;\n\n this._deflate.write(data);\n this._deflate.flush(zlib.Z_SYNC_FLUSH, () => {\n if (!this._deflate) {\n //\n // The deflate stream was closed while data was being processed.\n //\n return;\n }\n\n let data = bufferUtil.concat(\n this._deflate[kBuffers],\n this._deflate[kTotalLength]\n );\n\n if (fin) {\n data = new FastBuffer(data.buffer, data.byteOffset, data.length - 4);\n }\n\n //\n // Ensure that the callback will not be called again in\n // `PerMessageDeflate#cleanup()`.\n //\n this._deflate[kCallback] = null;\n\n this._deflate[kTotalLength] = 0;\n this._deflate[kBuffers] = [];\n\n if (fin && this.params[`${endpoint}_no_context_takeover`]) {\n this._deflate.reset();\n }\n\n callback(null, data);\n });\n }\n}\n\nmodule.exports = PerMessageDeflate;\n\n/**\n * The listener of the `zlib.DeflateRaw` stream `'data'` event.\n *\n * @param {Buffer} chunk A chunk of data\n * @private\n */\nfunction deflateOnData(chunk) {\n this[kBuffers].push(chunk);\n this[kTotalLength] += chunk.length;\n}\n\n/**\n * The listener of the `zlib.InflateRaw` stream `'data'` event.\n *\n * @param {Buffer} chunk A chunk of data\n * @private\n */\nfunction inflateOnData(chunk) {\n this[kTotalLength] += chunk.length;\n\n if (\n this[kPerMessageDeflate]._maxPayload < 1 ||\n this[kTotalLength] <= this[kPerMessageDeflate]._maxPayload\n ) {\n this[kBuffers].push(chunk);\n return;\n }\n\n this[kError] = new RangeError('Max payload size exceeded');\n this[kError].code = 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH';\n this[kError][kStatusCode] = 1009;\n this.removeListener('data', inflateOnData);\n this.reset();\n}\n\n/**\n * The listener of the `zlib.InflateRaw` stream `'error'` event.\n *\n * @param {Error} err The emitted error\n * @private\n */\nfunction inflateOnError(err) {\n //\n // There is no need to call `Zlib#close()` as the handle is automatically\n // closed when an error is emitted.\n //\n this[kPerMessageDeflate]._inflate = null;\n err[kStatusCode] = 1007;\n this[kCallback](err);\n}\n", "'use strict';\n\nconst { isUtf8 } = require('buffer');\n\n//\n// Allowed token characters:\n//\n// '!', '#', '$', '%', '&', ''', '*', '+', '-',\n// '.', 0-9, A-Z, '^', '_', '`', a-z, '|', '~'\n//\n// tokenChars[32] === 0 // ' '\n// tokenChars[33] === 1 // '!'\n// tokenChars[34] === 0 // '\"'\n// ...\n//\n// prettier-ignore\nconst tokenChars = [\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 - 15\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16 - 31\n 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, // 32 - 47\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 48 - 63\n 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 64 - 79\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, // 80 - 95\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 96 - 111\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0 // 112 - 127\n];\n\n/**\n * Checks if a status code is allowed in a close frame.\n *\n * @param {Number} code The status code\n * @return {Boolean} `true` if the status code is valid, else `false`\n * @public\n */\nfunction isValidStatusCode(code) {\n return (\n (code >= 1000 &&\n code <= 1014 &&\n code !== 1004 &&\n code !== 1005 &&\n code !== 1006) ||\n (code >= 3000 && code <= 4999)\n );\n}\n\n/**\n * Checks if a given buffer contains only correct UTF-8.\n * Ported from https://www.cl.cam.ac.uk/%7Emgk25/ucs/utf8_check.c by\n * Markus Kuhn.\n *\n * @param {Buffer} buf The buffer to check\n * @return {Boolean} `true` if `buf` contains only correct UTF-8, else `false`\n * @public\n */\nfunction _isValidUTF8(buf) {\n const len = buf.length;\n let i = 0;\n\n while (i < len) {\n if ((buf[i] & 0x80) === 0) {\n // 0xxxxxxx\n i++;\n } else if ((buf[i] & 0xe0) === 0xc0) {\n // 110xxxxx 10xxxxxx\n if (\n i + 1 === len ||\n (buf[i + 1] & 0xc0) !== 0x80 ||\n (buf[i] & 0xfe) === 0xc0 // Overlong\n ) {\n return false;\n }\n\n i += 2;\n } else if ((buf[i] & 0xf0) === 0xe0) {\n // 1110xxxx 10xxxxxx 10xxxxxx\n if (\n i + 2 >= len ||\n (buf[i + 1] & 0xc0) !== 0x80 ||\n (buf[i + 2] & 0xc0) !== 0x80 ||\n (buf[i] === 0xe0 && (buf[i + 1] & 0xe0) === 0x80) || // Overlong\n (buf[i] === 0xed && (buf[i + 1] & 0xe0) === 0xa0) // Surrogate (U+D800 - U+DFFF)\n ) {\n return false;\n }\n\n i += 3;\n } else if ((buf[i] & 0xf8) === 0xf0) {\n // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx\n if (\n i + 3 >= len ||\n (buf[i + 1] & 0xc0) !== 0x80 ||\n (buf[i + 2] & 0xc0) !== 0x80 ||\n (buf[i + 3] & 0xc0) !== 0x80 ||\n (buf[i] === 0xf0 && (buf[i + 1] & 0xf0) === 0x80) || // Overlong\n (buf[i] === 0xf4 && buf[i + 1] > 0x8f) ||\n buf[i] > 0xf4 // > U+10FFFF\n ) {\n return false;\n }\n\n i += 4;\n } else {\n return false;\n }\n }\n\n return true;\n}\n\nmodule.exports = {\n isValidStatusCode,\n isValidUTF8: _isValidUTF8,\n tokenChars\n};\n\nif (isUtf8) {\n module.exports.isValidUTF8 = function (buf) {\n return buf.length < 24 ? _isValidUTF8(buf) : isUtf8(buf);\n };\n} /* istanbul ignore else */ else if (!process.env.WS_NO_UTF_8_VALIDATE) {\n try {\n const isValidUTF8 = require('utf-8-validate');\n\n module.exports.isValidUTF8 = function (buf) {\n return buf.length < 32 ? _isValidUTF8(buf) : isValidUTF8(buf);\n };\n } catch (e) {\n // Continue regardless of the error.\n }\n}\n", "'use strict';\n\nconst { Writable } = require('stream');\n\nconst PerMessageDeflate = require('./permessage-deflate');\nconst {\n BINARY_TYPES,\n EMPTY_BUFFER,\n kStatusCode,\n kWebSocket\n} = require('./constants');\nconst { concat, toArrayBuffer, unmask } = require('./buffer-util');\nconst { isValidStatusCode, isValidUTF8 } = require('./validation');\n\nconst FastBuffer = Buffer[Symbol.species];\n\nconst GET_INFO = 0;\nconst GET_PAYLOAD_LENGTH_16 = 1;\nconst GET_PAYLOAD_LENGTH_64 = 2;\nconst GET_MASK = 3;\nconst GET_DATA = 4;\nconst INFLATING = 5;\nconst DEFER_EVENT = 6;\n\n/**\n * HyBi Receiver implementation.\n *\n * @extends Writable\n */\nclass Receiver extends Writable {\n /**\n * Creates a Receiver instance.\n *\n * @param {Object} [options] Options object\n * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether\n * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted\n * multiple times in the same tick\n * @param {String} [options.binaryType=nodebuffer] The type for binary data\n * @param {Object} [options.extensions] An object containing the negotiated\n * extensions\n * @param {Boolean} [options.isServer=false] Specifies whether to operate in\n * client or server mode\n * @param {Number} [options.maxPayload=0] The maximum allowed message length\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n */\n constructor(options = {}) {\n super();\n\n this._allowSynchronousEvents =\n options.allowSynchronousEvents !== undefined\n ? options.allowSynchronousEvents\n : true;\n this._binaryType = options.binaryType || BINARY_TYPES[0];\n this._extensions = options.extensions || {};\n this._isServer = !!options.isServer;\n this._maxPayload = options.maxPayload | 0;\n this._skipUTF8Validation = !!options.skipUTF8Validation;\n this[kWebSocket] = undefined;\n\n this._bufferedBytes = 0;\n this._buffers = [];\n\n this._compressed = false;\n this._payloadLength = 0;\n this._mask = undefined;\n this._fragmented = 0;\n this._masked = false;\n this._fin = false;\n this._opcode = 0;\n\n this._totalPayloadLength = 0;\n this._messageLength = 0;\n this._fragments = [];\n\n this._errored = false;\n this._loop = false;\n this._state = GET_INFO;\n }\n\n /**\n * Implements `Writable.prototype._write()`.\n *\n * @param {Buffer} chunk The chunk of data to write\n * @param {String} encoding The character encoding of `chunk`\n * @param {Function} cb Callback\n * @private\n */\n _write(chunk, encoding, cb) {\n if (this._opcode === 0x08 && this._state == GET_INFO) return cb();\n\n this._bufferedBytes += chunk.length;\n this._buffers.push(chunk);\n this.startLoop(cb);\n }\n\n /**\n * Consumes `n` bytes from the buffered data.\n *\n * @param {Number} n The number of bytes to consume\n * @return {Buffer} The consumed bytes\n * @private\n */\n consume(n) {\n this._bufferedBytes -= n;\n\n if (n === this._buffers[0].length) return this._buffers.shift();\n\n if (n < this._buffers[0].length) {\n const buf = this._buffers[0];\n this._buffers[0] = new FastBuffer(\n buf.buffer,\n buf.byteOffset + n,\n buf.length - n\n );\n\n return new FastBuffer(buf.buffer, buf.byteOffset, n);\n }\n\n const dst = Buffer.allocUnsafe(n);\n\n do {\n const buf = this._buffers[0];\n const offset = dst.length - n;\n\n if (n >= buf.length) {\n dst.set(this._buffers.shift(), offset);\n } else {\n dst.set(new Uint8Array(buf.buffer, buf.byteOffset, n), offset);\n this._buffers[0] = new FastBuffer(\n buf.buffer,\n buf.byteOffset + n,\n buf.length - n\n );\n }\n\n n -= buf.length;\n } while (n > 0);\n\n return dst;\n }\n\n /**\n * Starts the parsing loop.\n *\n * @param {Function} cb Callback\n * @private\n */\n startLoop(cb) {\n this._loop = true;\n\n do {\n switch (this._state) {\n case GET_INFO:\n this.getInfo(cb);\n break;\n case GET_PAYLOAD_LENGTH_16:\n this.getPayloadLength16(cb);\n break;\n case GET_PAYLOAD_LENGTH_64:\n this.getPayloadLength64(cb);\n break;\n case GET_MASK:\n this.getMask();\n break;\n case GET_DATA:\n this.getData(cb);\n break;\n case INFLATING:\n case DEFER_EVENT:\n this._loop = false;\n return;\n }\n } while (this._loop);\n\n if (!this._errored) cb();\n }\n\n /**\n * Reads the first two bytes of a frame.\n *\n * @param {Function} cb Callback\n * @private\n */\n getInfo(cb) {\n if (this._bufferedBytes < 2) {\n this._loop = false;\n return;\n }\n\n const buf = this.consume(2);\n\n if ((buf[0] & 0x30) !== 0x00) {\n const error = this.createError(\n RangeError,\n 'RSV2 and RSV3 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_2_3'\n );\n\n cb(error);\n return;\n }\n\n const compressed = (buf[0] & 0x40) === 0x40;\n\n if (compressed && !this._extensions[PerMessageDeflate.extensionName]) {\n const error = this.createError(\n RangeError,\n 'RSV1 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_1'\n );\n\n cb(error);\n return;\n }\n\n this._fin = (buf[0] & 0x80) === 0x80;\n this._opcode = buf[0] & 0x0f;\n this._payloadLength = buf[1] & 0x7f;\n\n if (this._opcode === 0x00) {\n if (compressed) {\n const error = this.createError(\n RangeError,\n 'RSV1 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_1'\n );\n\n cb(error);\n return;\n }\n\n if (!this._fragmented) {\n const error = this.createError(\n RangeError,\n 'invalid opcode 0',\n true,\n 1002,\n 'WS_ERR_INVALID_OPCODE'\n );\n\n cb(error);\n return;\n }\n\n this._opcode = this._fragmented;\n } else if (this._opcode === 0x01 || this._opcode === 0x02) {\n if (this._fragmented) {\n const error = this.createError(\n RangeError,\n `invalid opcode ${this._opcode}`,\n true,\n 1002,\n 'WS_ERR_INVALID_OPCODE'\n );\n\n cb(error);\n return;\n }\n\n this._compressed = compressed;\n } else if (this._opcode > 0x07 && this._opcode < 0x0b) {\n if (!this._fin) {\n const error = this.createError(\n RangeError,\n 'FIN must be set',\n true,\n 1002,\n 'WS_ERR_EXPECTED_FIN'\n );\n\n cb(error);\n return;\n }\n\n if (compressed) {\n const error = this.createError(\n RangeError,\n 'RSV1 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_1'\n );\n\n cb(error);\n return;\n }\n\n if (\n this._payloadLength > 0x7d ||\n (this._opcode === 0x08 && this._payloadLength === 1)\n ) {\n const error = this.createError(\n RangeError,\n `invalid payload length ${this._payloadLength}`,\n true,\n 1002,\n 'WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH'\n );\n\n cb(error);\n return;\n }\n } else {\n const error = this.createError(\n RangeError,\n `invalid opcode ${this._opcode}`,\n true,\n 1002,\n 'WS_ERR_INVALID_OPCODE'\n );\n\n cb(error);\n return;\n }\n\n if (!this._fin && !this._fragmented) this._fragmented = this._opcode;\n this._masked = (buf[1] & 0x80) === 0x80;\n\n if (this._isServer) {\n if (!this._masked) {\n const error = this.createError(\n RangeError,\n 'MASK must be set',\n true,\n 1002,\n 'WS_ERR_EXPECTED_MASK'\n );\n\n cb(error);\n return;\n }\n } else if (this._masked) {\n const error = this.createError(\n RangeError,\n 'MASK must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_