{"version":3,"file":"polyfill.mjs","sources":["../src/stub/symbol.ts","../src/utils.ts","../src/lib/helpers/miscellaneous.ts","../src/lib/helpers/webidl.ts","../src/lib/simple-queue.ts","../src/lib/readable-stream/generic-reader.ts","../src/lib/abstract-ops/internal-methods.ts","../src/stub/number-isfinite.ts","../src/stub/math-trunc.ts","../src/lib/validators/basic.ts","../src/lib/validators/readable-stream.ts","../src/lib/readable-stream/default-reader.ts","../src/target/es5/stub/async-iterator-prototype.ts","../src/lib/readable-stream/async-iterator.ts","../src/stub/number-isnan.ts","../src/lib/abstract-ops/ecmascript.ts","../src/lib/abstract-ops/miscellaneous.ts","../src/lib/abstract-ops/queue-with-sizes.ts","../src/lib/readable-stream/byte-stream-controller.ts","../src/lib/readable-stream/byob-reader.ts","../src/lib/abstract-ops/queuing-strategy.ts","../src/lib/validators/queuing-strategy.ts","../src/lib/validators/underlying-sink.ts","../src/lib/validators/writable-stream.ts","../src/lib/abort-signal.ts","../src/lib/writable-stream.ts","../src/stub/native.ts","../src/stub/dom-exception.ts","../src/lib/readable-stream/pipe.ts","../src/lib/readable-stream/default-controller.ts","../src/lib/readable-stream/tee.ts","../src/lib/validators/underlying-source.ts","../src/lib/validators/reader-options.ts","../src/lib/validators/iterator-options.ts","../src/lib/validators/pipe-options.ts","../src/lib/validators/readable-writable-pair.ts","../src/lib/readable-stream.ts","../src/lib/validators/queuing-strategy-init.ts","../src/lib/byte-length-queuing-strategy.ts","../src/lib/count-queuing-strategy.ts","../src/lib/validators/transformer.ts","../src/lib/transform-stream.ts","../src/polyfill.ts"],"sourcesContent":["/// \n\nconst SymbolPolyfill: (description?: string) => symbol =\n  typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ?\n    Symbol :\n    description => `Symbol(${description})` as any as symbol;\n\nexport default SymbolPolyfill;\n","/// \n\nexport function noop(): undefined {\n  return undefined;\n}\n\nfunction getGlobals() {\n  if (typeof self !== 'undefined') {\n    return self;\n  } else if (typeof window !== 'undefined') {\n    return window;\n  } else if (typeof global !== 'undefined') {\n    return global;\n  }\n  return undefined;\n}\n\nexport const globals = getGlobals();\n","import { noop } from '../../utils';\nimport { AssertionError } from '../../stub/assert';\n\nexport function typeIsObject(x: any): x is object {\n  return (typeof x === 'object' && x !== null) || typeof x === 'function';\n}\n\nexport const rethrowAssertionErrorRejection: (e: any) => void =\n  DEBUG ? e => {\n    // Used throughout the reference implementation, as `.catch(rethrowAssertionErrorRejection)`, to ensure any errors\n    // get shown. There are places in the spec where we do promise transformations and purposefully ignore or don't\n    // expect any errors, but assertion errors are always problematic.\n    if (e && e instanceof AssertionError) {\n      setTimeout(() => {\n        throw e;\n      }, 0);\n    }\n  } : noop;\n","import { globals } from '../../utils';\nimport { rethrowAssertionErrorRejection } from './miscellaneous';\nimport assert from '../../stub/assert';\n\nconst originalPromise = Promise;\nconst originalPromiseThen = Promise.prototype.then;\nconst originalPromiseResolve = Promise.resolve.bind(originalPromise);\nconst originalPromiseReject = Promise.reject.bind(originalPromise);\n\nexport function newPromise(executor: (\n  resolve: (value: T | PromiseLike) => void,\n  reject: (reason?: any) => void\n) => void): Promise {\n  return new originalPromise(executor);\n}\n\nexport function promiseResolvedWith(value: T | PromiseLike): Promise {\n  return originalPromiseResolve(value);\n}\n\nexport function promiseRejectedWith(reason: any): Promise {\n  return originalPromiseReject(reason);\n}\n\nexport function PerformPromiseThen(\n  promise: Promise,\n  onFulfilled?: (value: T) => TResult1 | PromiseLike,\n  onRejected?: (reason: any) => TResult2 | PromiseLike): Promise {\n  // There doesn't appear to be any way to correctly emulate the behaviour from JavaScript, so this is just an\n  // approximation.\n  return originalPromiseThen.call(promise, onFulfilled, onRejected) as Promise;\n}\n\nexport function uponPromise(\n  promise: Promise,\n  onFulfilled?: (value: T) => void | PromiseLike,\n  onRejected?: (reason: any) => void | PromiseLike): void {\n  PerformPromiseThen(\n    PerformPromiseThen(promise, onFulfilled, onRejected),\n    undefined,\n    rethrowAssertionErrorRejection\n  );\n}\n\nexport function uponFulfillment(promise: Promise, onFulfilled: (value: T) => void | PromiseLike): void {\n  uponPromise(promise, onFulfilled);\n}\n\nexport function uponRejection(promise: Promise, onRejected: (reason: any) => void | PromiseLike): void {\n  uponPromise(promise, undefined, onRejected);\n}\n\nexport function transformPromiseWith(\n  promise: Promise,\n  fulfillmentHandler?: (value: T) => TResult1 | PromiseLike,\n  rejectionHandler?: (reason: any) => TResult2 | PromiseLike): Promise {\n  return PerformPromiseThen(promise, fulfillmentHandler, rejectionHandler);\n}\n\nexport function setPromiseIsHandledToTrue(promise: Promise): void {\n  PerformPromiseThen(promise, undefined, rethrowAssertionErrorRejection);\n}\n\nexport const queueMicrotask: (fn: () => void) => void = (() => {\n  const globalQueueMicrotask = globals && globals.queueMicrotask;\n  if (typeof globalQueueMicrotask === 'function') {\n    return globalQueueMicrotask;\n  }\n\n  const resolvedPromise = promiseResolvedWith(undefined);\n  return (fn: () => void) => PerformPromiseThen(resolvedPromise, fn);\n})();\n\nexport function reflectCall(F: (this: T, ...fnArgs: A) => R, V: T, args: A): R {\n  if (typeof F !== 'function') {\n    throw new TypeError('Argument is not a function');\n  }\n  return Function.prototype.apply.call(F, V, args);\n}\n\nexport function promiseCall(F: (this: T, ...fnArgs: A) => R | PromiseLike,\n                                                   V: T,\n                                                   args: A): Promise {\n  assert(typeof F === 'function');\n  assert(V !== undefined);\n  assert(Array.isArray(args));\n  try {\n    return promiseResolvedWith(reflectCall(F, V, args));\n  } catch (value) {\n    return promiseRejectedWith(value);\n  }\n}\n","import assert from '../stub/assert';\n\n// Original from Chromium\n// https://chromium.googlesource.com/chromium/src/+/0aee4434a4dba42a42abaea9bfbc0cd196a63bc1/third_party/blink/renderer/core/streams/SimpleQueue.js\n\nconst QUEUE_MAX_ARRAY_SIZE = 16384;\n\ninterface Node {\n  _elements: T[];\n  _next: Node | undefined;\n}\n\n/**\n * Simple queue structure.\n *\n * Avoids scalability issues with using a packed array directly by using\n * multiple arrays in a linked list and keeping the array size bounded.\n */\nexport class SimpleQueue {\n  private _front: Node;\n  private _back: Node;\n  private _cursor = 0;\n  private _size = 0;\n\n  constructor() {\n    // _front and _back are always defined.\n    this._front = {\n      _elements: [],\n      _next: undefined\n    };\n    this._back = this._front;\n    // The cursor is used to avoid calling Array.shift().\n    // It contains the index of the front element of the array inside the\n    // front-most node. It is always in the range [0, QUEUE_MAX_ARRAY_SIZE).\n    this._cursor = 0;\n    // When there is only one node, size === elements.length - cursor.\n    this._size = 0;\n  }\n\n  get length(): number {\n    return this._size;\n  }\n\n  // For exception safety, this method is structured in order:\n  // 1. Read state\n  // 2. Calculate required state mutations\n  // 3. Perform state mutations\n  push(element: T): void {\n    const oldBack = this._back;\n    let newBack = oldBack;\n    assert(oldBack._next === undefined);\n    if (oldBack._elements.length === QUEUE_MAX_ARRAY_SIZE - 1) {\n      newBack = {\n        _elements: [],\n        _next: undefined\n      };\n    }\n\n    // push() is the mutation most likely to throw an exception, so it\n    // goes first.\n    oldBack._elements.push(element);\n    if (newBack !== oldBack) {\n      this._back = newBack;\n      oldBack._next = newBack;\n    }\n    ++this._size;\n  }\n\n  // Like push(), shift() follows the read -> calculate -> mutate pattern for\n  // exception safety.\n  shift(): T {\n    assert(this._size > 0); // must not be called on an empty queue\n\n    const oldFront = this._front;\n    let newFront = oldFront;\n    const oldCursor = this._cursor;\n    let newCursor = oldCursor + 1;\n\n    const elements = oldFront._elements;\n    const element = elements[oldCursor];\n\n    if (newCursor === QUEUE_MAX_ARRAY_SIZE) {\n      assert(elements.length === QUEUE_MAX_ARRAY_SIZE);\n      assert(oldFront._next !== undefined);\n      newFront = oldFront._next!;\n      newCursor = 0;\n    }\n\n    // No mutations before this point.\n    --this._size;\n    this._cursor = newCursor;\n    if (oldFront !== newFront) {\n      this._front = newFront;\n    }\n\n    // Permit shifted element to be garbage collected.\n    elements[oldCursor] = undefined!;\n\n    return element;\n  }\n\n  // The tricky thing about forEach() is that it can be called\n  // re-entrantly. The queue may be mutated inside the callback. It is easy to\n  // see that push() within the callback has no negative effects since the end\n  // of the queue is checked for on every iteration. If shift() is called\n  // repeatedly within the callback then the next iteration may return an\n  // element that has been removed. In this case the callback will be called\n  // with undefined values until we either \"catch up\" with elements that still\n  // exist or reach the back of the queue.\n  forEach(callback: (element: T) => void): void {\n    let i = this._cursor;\n    let node = this._front;\n    let elements = node._elements;\n    while (i !== elements.length || node._next !== undefined) {\n      if (i === elements.length) {\n        assert(node._next !== undefined);\n        assert(i === QUEUE_MAX_ARRAY_SIZE);\n        node = node._next!;\n        elements = node._elements;\n        i = 0;\n        if (elements.length === 0) {\n          break;\n        }\n      }\n      callback(elements[i]);\n      ++i;\n    }\n  }\n\n  // Return the element that would be returned if shift() was called now,\n  // without modifying the queue.\n  peek(): T {\n    assert(this._size > 0); // must not be called on an empty queue\n\n    const front = this._front;\n    const cursor = this._cursor;\n    return front._elements[cursor];\n  }\n}\n","import assert from '../../stub/assert';\nimport { ReadableStream, ReadableStreamCancel, ReadableStreamReader } from '../readable-stream';\nimport { newPromise, setPromiseIsHandledToTrue } from '../helpers/webidl';\n\nexport function ReadableStreamReaderGenericInitialize(reader: ReadableStreamReader, stream: ReadableStream) {\n  reader._ownerReadableStream = stream;\n  stream._reader = reader;\n\n  if (stream._state === 'readable') {\n    defaultReaderClosedPromiseInitialize(reader);\n  } else if (stream._state === 'closed') {\n    defaultReaderClosedPromiseInitializeAsResolved(reader);\n  } else {\n    assert(stream._state === 'errored');\n\n    defaultReaderClosedPromiseInitializeAsRejected(reader, stream._storedError);\n  }\n}\n\n// A client of ReadableStreamDefaultReader and ReadableStreamBYOBReader may use these functions directly to bypass state\n// check.\n\nexport function ReadableStreamReaderGenericCancel(reader: ReadableStreamReader, reason: any): Promise {\n  const stream = reader._ownerReadableStream;\n  assert(stream !== undefined);\n  return ReadableStreamCancel(stream, reason);\n}\n\nexport function ReadableStreamReaderGenericRelease(reader: ReadableStreamReader) {\n  assert(reader._ownerReadableStream !== undefined);\n  assert(reader._ownerReadableStream._reader === reader);\n\n  if (reader._ownerReadableStream._state === 'readable') {\n    defaultReaderClosedPromiseReject(\n      reader,\n      new TypeError(`Reader was released and can no longer be used to monitor the stream's closedness`));\n  } else {\n    defaultReaderClosedPromiseResetToRejected(\n      reader,\n      new TypeError(`Reader was released and can no longer be used to monitor the stream's closedness`));\n  }\n\n  reader._ownerReadableStream._reader = undefined;\n  reader._ownerReadableStream = undefined!;\n}\n\n// Helper functions for the readers.\n\nexport function readerLockException(name: string): TypeError {\n  return new TypeError('Cannot ' + name + ' a stream using a released reader');\n}\n\n// Helper functions for the ReadableStreamDefaultReader.\n\nexport function defaultReaderClosedPromiseInitialize(reader: ReadableStreamReader) {\n  reader._closedPromise = newPromise((resolve, reject) => {\n    reader._closedPromise_resolve = resolve;\n    reader._closedPromise_reject = reject;\n  });\n}\n\nexport function defaultReaderClosedPromiseInitializeAsRejected(reader: ReadableStreamReader, reason: any) {\n  defaultReaderClosedPromiseInitialize(reader);\n  defaultReaderClosedPromiseReject(reader, reason);\n}\n\nexport function defaultReaderClosedPromiseInitializeAsResolved(reader: ReadableStreamReader) {\n  defaultReaderClosedPromiseInitialize(reader);\n  defaultReaderClosedPromiseResolve(reader);\n}\n\nexport function defaultReaderClosedPromiseReject(reader: ReadableStreamReader, reason: any) {\n  if (reader._closedPromise_reject === undefined) {\n    return;\n  }\n\n  setPromiseIsHandledToTrue(reader._closedPromise);\n  reader._closedPromise_reject(reason);\n  reader._closedPromise_resolve = undefined;\n  reader._closedPromise_reject = undefined;\n}\n\nexport function defaultReaderClosedPromiseResetToRejected(reader: ReadableStreamReader, reason: any) {\n  assert(reader._closedPromise_resolve === undefined);\n  assert(reader._closedPromise_reject === undefined);\n\n  defaultReaderClosedPromiseInitializeAsRejected(reader, reason);\n}\n\nexport function defaultReaderClosedPromiseResolve(reader: ReadableStreamReader) {\n  if (reader._closedPromise_resolve === undefined) {\n    return;\n  }\n\n  reader._closedPromise_resolve(undefined);\n  reader._closedPromise_resolve = undefined;\n  reader._closedPromise_reject = undefined;\n}\n","export const AbortSteps = Symbol('[[AbortSteps]]');\nexport const ErrorSteps = Symbol('[[ErrorSteps]]');\nexport const CancelSteps = Symbol('[[CancelSteps]]');\nexport const PullSteps = Symbol('[[PullSteps]]');\n","/// \n\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite#Polyfill\nconst NumberIsFinite: typeof Number.isFinite = Number.isFinite || function (x) {\n  return typeof x === 'number' && isFinite(x);\n};\n\nexport default NumberIsFinite;\n","/// \n\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc#Polyfill\nconst MathTrunc: typeof Math.trunc = Math.trunc || function (v) {\n  return v < 0 ? Math.ceil(v) : Math.floor(v);\n};\n\nexport default MathTrunc;\n","import NumberIsFinite from '../../stub/number-isfinite';\nimport MathTrunc from '../../stub/math-trunc';\n\n// https://heycam.github.io/webidl/#idl-dictionaries\nexport function isDictionary(x: any): x is object | null {\n  return typeof x === 'object' || typeof x === 'function';\n}\n\nexport function assertDictionary(obj: unknown,\n                                 context: string): asserts obj is object | null | undefined {\n  if (obj !== undefined && !isDictionary(obj)) {\n    throw new TypeError(`${context} is not an object.`);\n  }\n}\n\nexport type AnyFunction = (...args: any[]) => any;\n\n// https://heycam.github.io/webidl/#idl-callback-functions\nexport function assertFunction(x: unknown, context: string): asserts x is AnyFunction {\n  if (typeof x !== 'function') {\n    throw new TypeError(`${context} is not a function.`);\n  }\n}\n\n// https://heycam.github.io/webidl/#idl-object\nexport function isObject(x: any): x is object {\n  return (typeof x === 'object' && x !== null) || typeof x === 'function';\n}\n\nexport function assertObject(x: unknown,\n                             context: string): asserts x is object {\n  if (!isObject(x)) {\n    throw new TypeError(`${context} is not an object.`);\n  }\n}\n\nexport function assertRequiredArgument(x: T | undefined,\n                                                      position: number,\n                                                      context: string): asserts x is T {\n  if (x === undefined) {\n    throw new TypeError(`Parameter ${position} is required in '${context}'.`);\n  }\n}\n\nexport function assertRequiredField(x: T | undefined,\n                                                   field: string,\n                                                   context: string): asserts x is T {\n  if (x === undefined) {\n    throw new TypeError(`${field} is required in '${context}'.`);\n  }\n}\n\n// https://heycam.github.io/webidl/#idl-unrestricted-double\nexport function convertUnrestrictedDouble(value: unknown): number {\n  return Number(value);\n}\n\nfunction censorNegativeZero(x: number): number {\n  return x === 0 ? 0 : x;\n}\n\nfunction integerPart(x: number): number {\n  return censorNegativeZero(MathTrunc(x));\n}\n\n// https://heycam.github.io/webidl/#idl-unsigned-long-long\nexport function convertUnsignedLongLongWithEnforceRange(value: unknown, context: string): number {\n  const lowerBound = 0;\n  const upperBound = Number.MAX_SAFE_INTEGER;\n\n  let x = Number(value);\n  x = censorNegativeZero(x);\n\n  if (!NumberIsFinite(x)) {\n    throw new TypeError(`${context} is not a finite number`);\n  }\n\n  x = integerPart(x);\n\n  if (x < lowerBound || x > upperBound) {\n    throw new TypeError(`${context} is outside the accepted range of ${lowerBound} to ${upperBound}, inclusive`);\n  }\n\n  if (!NumberIsFinite(x) || x === 0) {\n    return 0;\n  }\n\n  // TODO Use BigInt if supported?\n  // let xBigInt = BigInt(integerPart(x));\n  // xBigInt = BigInt.asUintN(64, xBigInt);\n  // return Number(xBigInt);\n\n  return x;\n}\n","import { IsReadableStream, ReadableStream } from '../readable-stream';\n\nexport function assertReadableStream(x: unknown, context: string): asserts x is ReadableStream {\n  if (!IsReadableStream(x)) {\n    throw new TypeError(`${context} is not a ReadableStream.`);\n  }\n}\n","import assert from '../../stub/assert';\nimport { SimpleQueue } from '../simple-queue';\nimport {\n  ReadableStreamReaderGenericCancel,\n  ReadableStreamReaderGenericInitialize,\n  ReadableStreamReaderGenericRelease,\n  readerLockException\n} from './generic-reader';\nimport { IsReadableStreamLocked, ReadableStream } from '../readable-stream';\nimport { typeIsObject } from '../helpers/miscellaneous';\nimport { PullSteps } from '../abstract-ops/internal-methods';\nimport { newPromise, promiseRejectedWith } from '../helpers/webidl';\nimport { assertRequiredArgument } from '../validators/basic';\nimport { assertReadableStream } from '../validators/readable-stream';\n\n/**\n * A result returned by {@link ReadableStreamDefaultReader.read}.\n *\n * @public\n */\nexport type ReadableStreamDefaultReadResult = {\n  done: false;\n  value: T;\n} | {\n  done: true;\n  value?: undefined;\n}\n\n// Abstract operations for the ReadableStream.\n\nexport function AcquireReadableStreamDefaultReader(stream: ReadableStream): ReadableStreamDefaultReader {\n  return new ReadableStreamDefaultReader(stream);\n}\n\n// ReadableStream API exposed for controllers.\n\nexport function ReadableStreamAddReadRequest(stream: ReadableStream,\n                                                readRequest: ReadRequest): void {\n  assert(IsReadableStreamDefaultReader(stream._reader));\n  assert(stream._state === 'readable');\n\n  (stream._reader! as ReadableStreamDefaultReader)._readRequests.push(readRequest);\n}\n\nexport function ReadableStreamFulfillReadRequest(stream: ReadableStream, chunk: R | undefined, done: boolean) {\n  const reader = stream._reader as ReadableStreamDefaultReader;\n\n  assert(reader._readRequests.length > 0);\n\n  const readRequest = reader._readRequests.shift()!;\n  if (done) {\n    readRequest._closeSteps();\n  } else {\n    readRequest._chunkSteps(chunk!);\n  }\n}\n\nexport function ReadableStreamGetNumReadRequests(stream: ReadableStream): number {\n  return (stream._reader as ReadableStreamDefaultReader)._readRequests.length;\n}\n\nexport function ReadableStreamHasDefaultReader(stream: ReadableStream): boolean {\n  const reader = stream._reader;\n\n  if (reader === undefined) {\n    return false;\n  }\n\n  if (!IsReadableStreamDefaultReader(reader)) {\n    return false;\n  }\n\n  return true;\n}\n\n// Readers\n\nexport interface ReadRequest {\n  _chunkSteps(chunk: R): void;\n\n  _closeSteps(): void;\n\n  _errorSteps(e: any): void;\n}\n\n/**\n * A default reader vended by a {@link ReadableStream}.\n *\n * @public\n */\nexport class ReadableStreamDefaultReader {\n  /** @internal */\n  _ownerReadableStream!: ReadableStream;\n  /** @internal */\n  _closedPromise!: Promise;\n  /** @internal */\n  _closedPromise_resolve?: (value?: undefined) => void;\n  /** @internal */\n  _closedPromise_reject?: (reason: any) => void;\n  /** @internal */\n  _readRequests: SimpleQueue>;\n\n  constructor(stream: ReadableStream) {\n    assertRequiredArgument(stream, 1, 'ReadableStreamDefaultReader');\n    assertReadableStream(stream, 'First parameter');\n\n    if (IsReadableStreamLocked(stream)) {\n      throw new TypeError('This stream has already been locked for exclusive reading by another reader');\n    }\n\n    ReadableStreamReaderGenericInitialize(this, stream);\n\n    this._readRequests = new SimpleQueue();\n  }\n\n  /**\n   * Returns a promise that will be fulfilled when the stream becomes closed,\n   * or rejected if the stream ever errors or the reader's lock is released before the stream finishes closing.\n   */\n  get closed(): Promise {\n    if (!IsReadableStreamDefaultReader(this)) {\n      return promiseRejectedWith(defaultReaderBrandCheckException('closed'));\n    }\n\n    return this._closedPromise;\n  }\n\n  /**\n   * If the reader is active, behaves the same as {@link ReadableStream.cancel | stream.cancel(reason)}.\n   */\n  cancel(reason: any = undefined): Promise {\n    if (!IsReadableStreamDefaultReader(this)) {\n      return promiseRejectedWith(defaultReaderBrandCheckException('cancel'));\n    }\n\n    if (this._ownerReadableStream === undefined) {\n      return promiseRejectedWith(readerLockException('cancel'));\n    }\n\n    return ReadableStreamReaderGenericCancel(this, reason);\n  }\n\n  /**\n   * Returns a promise that allows access to the next chunk from the stream's internal queue, if available.\n   *\n   * If reading a chunk causes the queue to become empty, more data will be pulled from the underlying source.\n   */\n  read(): Promise> {\n    if (!IsReadableStreamDefaultReader(this)) {\n      return promiseRejectedWith(defaultReaderBrandCheckException('read'));\n    }\n\n    if (this._ownerReadableStream === undefined) {\n      return promiseRejectedWith(readerLockException('read from'));\n    }\n\n    let resolvePromise!: (result: ReadableStreamDefaultReadResult) => void;\n    let rejectPromise!: (reason: any) => void;\n    const promise = newPromise>((resolve, reject) => {\n      resolvePromise = resolve;\n      rejectPromise = reject;\n    });\n    const readRequest: ReadRequest = {\n      _chunkSteps: chunk => resolvePromise({ value: chunk, done: false }),\n      _closeSteps: () => resolvePromise({ value: undefined, done: true }),\n      _errorSteps: e => rejectPromise(e)\n    };\n    ReadableStreamDefaultReaderRead(this, readRequest);\n    return promise;\n  }\n\n  /**\n   * Releases the reader's lock on the corresponding stream. After the lock is released, the reader is no longer active.\n   * If the associated stream is errored when the lock is released, the reader will appear errored in the same way\n   * from now on; otherwise, the reader will appear closed.\n   *\n   * A reader's lock cannot be released while it still has a pending read request, i.e., if a promise returned by\n   * the reader's {@link ReadableStreamDefaultReader.read | read()} method has not yet been settled. Attempting to\n   * do so will throw a `TypeError` and leave the reader locked to the stream.\n   */\n  releaseLock(): void {\n    if (!IsReadableStreamDefaultReader(this)) {\n      throw defaultReaderBrandCheckException('releaseLock');\n    }\n\n    if (this._ownerReadableStream === undefined) {\n      return;\n    }\n\n    if (this._readRequests.length > 0) {\n      throw new TypeError('Tried to release a reader lock when that reader has pending read() calls un-settled');\n    }\n\n    ReadableStreamReaderGenericRelease(this);\n  }\n}\n\nObject.defineProperties(ReadableStreamDefaultReader.prototype, {\n  cancel: { enumerable: true },\n  read: { enumerable: true },\n  releaseLock: { enumerable: true },\n  closed: { enumerable: true }\n});\nif (typeof Symbol.toStringTag === 'symbol') {\n  Object.defineProperty(ReadableStreamDefaultReader.prototype, Symbol.toStringTag, {\n    value: 'ReadableStreamDefaultReader',\n    configurable: true\n  });\n}\n\n// Abstract operations for the readers.\n\nexport function IsReadableStreamDefaultReader(x: any): x is ReadableStreamDefaultReader {\n  if (!typeIsObject(x)) {\n    return false;\n  }\n\n  if (!Object.prototype.hasOwnProperty.call(x, '_readRequests')) {\n    return false;\n  }\n\n  return x instanceof ReadableStreamDefaultReader;\n}\n\nexport function ReadableStreamDefaultReaderRead(reader: ReadableStreamDefaultReader,\n                                                   readRequest: ReadRequest): void {\n  const stream = reader._ownerReadableStream;\n\n  assert(stream !== undefined);\n\n  stream._disturbed = true;\n\n  if (stream._state === 'closed') {\n    readRequest._closeSteps();\n  } else if (stream._state === 'errored') {\n    readRequest._errorSteps(stream._storedError);\n  } else {\n    assert(stream._state === 'readable');\n    stream._readableStreamController[PullSteps](readRequest as ReadRequest);\n  }\n}\n\n// Helper functions for the ReadableStreamDefaultReader.\n\nfunction defaultReaderBrandCheckException(name: string): TypeError {\n  return new TypeError(\n    `ReadableStreamDefaultReader.prototype.${name} can only be used on a ReadableStreamDefaultReader`);\n}\n","/// \n\nexport let AsyncIteratorPrototype: AsyncIterable | undefined;\n\nif (typeof Symbol.asyncIterator === 'symbol') {\n  // We're running inside a ES2018+ environment, but we're compiling to an older syntax.\n  // We cannot access %AsyncIteratorPrototype% without non-ES2018 syntax, but we can re-create it.\n  AsyncIteratorPrototype = {\n    // 25.1.3.1 %AsyncIteratorPrototype% [ @@asyncIterator ] ( )\n    // https://tc39.github.io/ecma262/#sec-asynciteratorprototype-asynciterator\n    [Symbol.asyncIterator](this: AsyncIterator) {\n      return this;\n    }\n  };\n  Object.defineProperty(AsyncIteratorPrototype, Symbol.asyncIterator, { enumerable: false });\n}\n","/// \n\nimport { ReadableStream } from '../readable-stream';\nimport {\n  AcquireReadableStreamDefaultReader,\n  ReadableStreamDefaultReader,\n  ReadableStreamDefaultReaderRead,\n  ReadableStreamDefaultReadResult,\n  ReadRequest\n} from './default-reader';\nimport {\n  ReadableStreamReaderGenericCancel,\n  ReadableStreamReaderGenericRelease,\n  readerLockException\n} from './generic-reader';\nimport assert from '../../stub/assert';\nimport { AsyncIteratorPrototype } from '@@target/stub/async-iterator-prototype';\nimport { typeIsObject } from '../helpers/miscellaneous';\nimport {\n  newPromise,\n  promiseRejectedWith,\n  promiseResolvedWith,\n  queueMicrotask,\n  transformPromiseWith\n} from '../helpers/webidl';\n\n/**\n * An async iterator returned by {@link ReadableStream.values}.\n *\n * @public\n */\nexport interface ReadableStreamAsyncIterator extends AsyncIterator {\n  next(): Promise>;\n\n  return(value?: any): Promise>;\n}\n\nexport class ReadableStreamAsyncIteratorImpl {\n  private readonly _reader: ReadableStreamDefaultReader;\n  private readonly _preventCancel: boolean;\n  private _ongoingPromise: Promise> | undefined = undefined;\n  private _isFinished = false;\n\n  constructor(reader: ReadableStreamDefaultReader, preventCancel: boolean) {\n    this._reader = reader;\n    this._preventCancel = preventCancel;\n  }\n\n  next(): Promise> {\n    const nextSteps = () => this._nextSteps();\n    this._ongoingPromise = this._ongoingPromise ?\n      transformPromiseWith(this._ongoingPromise, nextSteps, nextSteps) :\n      nextSteps();\n    return this._ongoingPromise;\n  }\n\n  return(value: any): Promise> {\n    const returnSteps = () => this._returnSteps(value);\n    return this._ongoingPromise ?\n      transformPromiseWith(this._ongoingPromise, returnSteps, returnSteps) :\n      returnSteps();\n  }\n\n  private _nextSteps(): Promise> {\n    if (this._isFinished) {\n      return Promise.resolve({ value: undefined, done: true });\n    }\n\n    const reader = this._reader;\n    if (reader._ownerReadableStream === undefined) {\n      return promiseRejectedWith(readerLockException('iterate'));\n    }\n\n    let resolvePromise!: (result: ReadableStreamDefaultReadResult) => void;\n    let rejectPromise!: (reason: any) => void;\n    const promise = newPromise>((resolve, reject) => {\n      resolvePromise = resolve;\n      rejectPromise = reject;\n    });\n    const readRequest: ReadRequest = {\n      _chunkSteps: chunk => {\n        this._ongoingPromise = undefined;\n        // This needs to be delayed by one microtask, otherwise we stop pulling too early which breaks a test.\n        // FIXME Is this a bug in the specification, or in the test?\n        queueMicrotask(() => resolvePromise({ value: chunk, done: false }));\n      },\n      _closeSteps: () => {\n        this._ongoingPromise = undefined;\n        this._isFinished = true;\n        ReadableStreamReaderGenericRelease(reader);\n        resolvePromise({ value: undefined, done: true });\n      },\n      _errorSteps: reason => {\n        this._ongoingPromise = undefined;\n        this._isFinished = true;\n        ReadableStreamReaderGenericRelease(reader);\n        rejectPromise(reason);\n      }\n    };\n    ReadableStreamDefaultReaderRead(reader, readRequest);\n    return promise;\n  }\n\n  private _returnSteps(value: any): Promise> {\n    if (this._isFinished) {\n      return Promise.resolve({ value, done: true });\n    }\n    this._isFinished = true;\n\n    const reader = this._reader;\n    if (reader._ownerReadableStream === undefined) {\n      return promiseRejectedWith(readerLockException('finish iterating'));\n    }\n\n    assert(reader._readRequests.length === 0);\n\n    if (!this._preventCancel) {\n      const result = ReadableStreamReaderGenericCancel(reader, value);\n      ReadableStreamReaderGenericRelease(reader);\n      return transformPromiseWith(result, () => ({ value, done: true }));\n    }\n\n    ReadableStreamReaderGenericRelease(reader);\n    return promiseResolvedWith({ value, done: true });\n  }\n}\n\ndeclare class ReadableStreamAsyncIteratorInstance implements ReadableStreamAsyncIterator {\n  /** @interal */\n  _asyncIteratorImpl: ReadableStreamAsyncIteratorImpl;\n\n  next(): Promise>;\n\n  return(value?: any): Promise>;\n}\n\nconst ReadableStreamAsyncIteratorPrototype: ReadableStreamAsyncIteratorInstance = {\n  next(this: ReadableStreamAsyncIteratorInstance): Promise> {\n    if (!IsReadableStreamAsyncIterator(this)) {\n      return promiseRejectedWith(streamAsyncIteratorBrandCheckException('next'));\n    }\n    return this._asyncIteratorImpl.next();\n  },\n\n  return(this: ReadableStreamAsyncIteratorInstance, value: any): Promise> {\n    if (!IsReadableStreamAsyncIterator(this)) {\n      return promiseRejectedWith(streamAsyncIteratorBrandCheckException('return'));\n    }\n    return this._asyncIteratorImpl.return(value);\n  }\n} as any;\nif (AsyncIteratorPrototype !== undefined) {\n  Object.setPrototypeOf(ReadableStreamAsyncIteratorPrototype, AsyncIteratorPrototype);\n}\n\n// Abstract operations for the ReadableStream.\n\nexport function AcquireReadableStreamAsyncIterator(stream: ReadableStream,\n                                                      preventCancel: boolean): ReadableStreamAsyncIterator {\n  const reader = AcquireReadableStreamDefaultReader(stream);\n  const impl = new ReadableStreamAsyncIteratorImpl(reader, preventCancel);\n  const iterator: ReadableStreamAsyncIteratorInstance = Object.create(ReadableStreamAsyncIteratorPrototype);\n  iterator._asyncIteratorImpl = impl;\n  return iterator;\n}\n\nfunction IsReadableStreamAsyncIterator(x: any): x is ReadableStreamAsyncIterator {\n  if (!typeIsObject(x)) {\n    return false;\n  }\n\n  if (!Object.prototype.hasOwnProperty.call(x, '_asyncIteratorImpl')) {\n    return false;\n  }\n\n  try {\n    // noinspection SuspiciousTypeOfGuard\n    return (x as ReadableStreamAsyncIteratorInstance)._asyncIteratorImpl instanceof\n      ReadableStreamAsyncIteratorImpl;\n  } catch {\n    return false;\n  }\n}\n\n// Helper functions for the ReadableStream.\n\nfunction streamAsyncIteratorBrandCheckException(name: string): TypeError {\n  return new TypeError(`ReadableStreamAsyncIterator.${name} can only be used on a ReadableSteamAsyncIterator`);\n}\n","/// \n\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN#Polyfill\nconst NumberIsNaN: typeof Number.isNaN = Number.isNaN || function (x) {\n  // eslint-disable-next-line no-self-compare\n  return x !== x;\n};\n\nexport default NumberIsNaN;\n","export function CreateArrayFromList(elements: T): T {\n  // We use arrays to represent lists, so this is basically a no-op.\n  // Do a slice though just in case we happen to depend on the unique-ness.\n  return elements.slice() as T;\n}\n\nexport function CopyDataBlockBytes(dest: ArrayBuffer,\n                                   destOffset: number,\n                                   src: ArrayBuffer,\n                                   srcOffset: number,\n                                   n: number) {\n  new Uint8Array(dest).set(new Uint8Array(src, srcOffset, n), destOffset);\n}\n\n// Not implemented correctly\nexport function TransferArrayBuffer(O: T): T {\n  return O;\n}\n\n// Not implemented correctly\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport function CanTransferArrayBuffer(O: ArrayBufferLike): boolean {\n  return true;\n}\n\n// Not implemented correctly\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport function IsDetachedBuffer(O: ArrayBufferLike): boolean {\n  return false;\n}\n\nexport function ArrayBufferSlice(buffer: ArrayBufferLike, begin: number, end: number): ArrayBufferLike {\n  // ArrayBuffer.prototype.slice is not available on IE10\n  // https://www.caniuse.com/mdn-javascript_builtins_arraybuffer_slice\n  if (buffer.slice) {\n    return buffer.slice(begin, end);\n  }\n  const length = end - begin;\n  const slice = new ArrayBuffer(length);\n  CopyDataBlockBytes(slice, 0, buffer, begin, length);\n  return slice;\n}\n","import NumberIsNaN from '../../stub/number-isnan';\nimport { ArrayBufferSlice } from './ecmascript';\n\nexport function IsNonNegativeNumber(v: number): boolean {\n  if (typeof v !== 'number') {\n    return false;\n  }\n\n  if (NumberIsNaN(v)) {\n    return false;\n  }\n\n  if (v < 0) {\n    return false;\n  }\n\n  return true;\n}\n\nexport function CloneAsUint8Array(O: ArrayBufferView): Uint8Array {\n  const buffer = ArrayBufferSlice(O.buffer, O.byteOffset, O.byteOffset + O.byteLength);\n  return new Uint8Array(buffer);\n}\n","import assert from '../../stub/assert';\nimport { SimpleQueue } from '../simple-queue';\nimport { IsNonNegativeNumber } from './miscellaneous';\n\nexport interface QueueContainer {\n  _queue: SimpleQueue;\n  _queueTotalSize: number;\n}\n\nexport interface QueuePair {\n  value: T;\n  size: number;\n}\n\nexport function DequeueValue(container: QueueContainer>): T {\n  assert('_queue' in container && '_queueTotalSize' in container);\n  assert(container._queue.length > 0);\n\n  const pair = container._queue.shift()!;\n  container._queueTotalSize -= pair.size;\n  if (container._queueTotalSize < 0) {\n    container._queueTotalSize = 0;\n  }\n\n  return pair.value;\n}\n\nexport function EnqueueValueWithSize(container: QueueContainer>, value: T, size: number) {\n  assert('_queue' in container && '_queueTotalSize' in container);\n\n  if (!IsNonNegativeNumber(size) || size === Infinity) {\n    throw new RangeError('Size must be a finite, non-NaN, non-negative number.');\n  }\n\n  container._queue.push({ value, size });\n  container._queueTotalSize += size;\n}\n\nexport function PeekQueueValue(container: QueueContainer>): T {\n  assert('_queue' in container && '_queueTotalSize' in container);\n  assert(container._queue.length > 0);\n\n  const pair = container._queue.peek();\n  return pair.value;\n}\n\nexport function ResetQueue(container: QueueContainer) {\n  assert('_queue' in container && '_queueTotalSize' in container);\n\n  container._queue = new SimpleQueue();\n  container._queueTotalSize = 0;\n}\n","import assert from '../../stub/assert';\nimport { SimpleQueue } from '../simple-queue';\nimport { ResetQueue } from '../abstract-ops/queue-with-sizes';\nimport {\n  ReadableStreamAddReadRequest,\n  ReadableStreamFulfillReadRequest,\n  ReadableStreamGetNumReadRequests,\n  ReadableStreamHasDefaultReader,\n  ReadRequest\n} from './default-reader';\nimport {\n  ReadableStreamAddReadIntoRequest,\n  ReadableStreamFulfillReadIntoRequest,\n  ReadableStreamGetNumReadIntoRequests,\n  ReadableStreamHasBYOBReader,\n  ReadIntoRequest\n} from './byob-reader';\nimport NumberIsInteger from '../../stub/number-isinteger';\nimport {\n  IsReadableStreamLocked,\n  ReadableByteStream,\n  ReadableStreamClose,\n  ReadableStreamError\n} from '../readable-stream';\nimport { ValidatedUnderlyingByteSource } from './underlying-source';\nimport { typeIsObject } from '../helpers/miscellaneous';\nimport {\n  ArrayBufferSlice,\n  CanTransferArrayBuffer,\n  CopyDataBlockBytes,\n  IsDetachedBuffer,\n  TransferArrayBuffer\n} from '../abstract-ops/ecmascript';\nimport { CancelSteps, PullSteps } from '../abstract-ops/internal-methods';\nimport { promiseResolvedWith, uponPromise } from '../helpers/webidl';\nimport { assertRequiredArgument, convertUnsignedLongLongWithEnforceRange } from '../validators/basic';\n\n/**\n * A pull-into request in a {@link ReadableByteStreamController}.\n *\n * @public\n */\nexport class ReadableStreamBYOBRequest {\n  /** @internal */\n  _associatedReadableByteStreamController!: ReadableByteStreamController;\n  /** @internal */\n  _view!: ArrayBufferView | null;\n\n  private constructor() {\n    throw new TypeError('Illegal constructor');\n  }\n\n  /**\n   * Returns the view for writing in to, or `null` if the BYOB request has already been responded to.\n   */\n  get view(): ArrayBufferView | null {\n    if (!IsReadableStreamBYOBRequest(this)) {\n      throw byobRequestBrandCheckException('view');\n    }\n\n    return this._view;\n  }\n\n  /**\n   * Indicates to the associated readable byte stream that `bytesWritten` bytes were written into\n   * {@link ReadableStreamBYOBRequest.view | view}, causing the result be surfaced to the consumer.\n   *\n   * After this method is called, {@link ReadableStreamBYOBRequest.view | view} will be transferred and no longer\n   * modifiable.\n   */\n  respond(bytesWritten: number): void;\n  respond(bytesWritten: number | undefined): void {\n    if (!IsReadableStreamBYOBRequest(this)) {\n      throw byobRequestBrandCheckException('respond');\n    }\n    assertRequiredArgument(bytesWritten, 1, 'respond');\n    bytesWritten = convertUnsignedLongLongWithEnforceRange(bytesWritten, 'First parameter');\n\n    if (this._associatedReadableByteStreamController === undefined) {\n      throw new TypeError('This BYOB request has been invalidated');\n    }\n\n    if (IsDetachedBuffer(this._view!.buffer)) {\n      throw new TypeError(`The BYOB request's buffer has been detached and so cannot be used as a response`);\n    }\n\n    assert(this._view!.byteLength > 0);\n    assert(this._view!.buffer.byteLength > 0);\n\n    ReadableByteStreamControllerRespond(this._associatedReadableByteStreamController, bytesWritten);\n  }\n\n  /**\n   * Indicates to the associated readable byte stream that instead of writing into\n   * {@link ReadableStreamBYOBRequest.view | view}, the underlying byte source is providing a new `ArrayBufferView`,\n   * which will be given to the consumer of the readable byte stream.\n   *\n   * After this method is called, `view` will be transferred and no longer modifiable.\n   */\n  respondWithNewView(view: ArrayBufferView): void;\n  respondWithNewView(view: ArrayBufferView | undefined): void {\n    if (!IsReadableStreamBYOBRequest(this)) {\n      throw byobRequestBrandCheckException('respondWithNewView');\n    }\n    assertRequiredArgument(view, 1, 'respondWithNewView');\n\n    if (!ArrayBuffer.isView(view)) {\n      throw new TypeError('You can only respond with array buffer views');\n    }\n\n    if (this._associatedReadableByteStreamController === undefined) {\n      throw new TypeError('This BYOB request has been invalidated');\n    }\n\n    if (IsDetachedBuffer(view.buffer)) {\n      throw new TypeError('The given view\\'s buffer has been detached and so cannot be used as a response');\n    }\n\n    ReadableByteStreamControllerRespondWithNewView(this._associatedReadableByteStreamController, view);\n  }\n}\n\nObject.defineProperties(ReadableStreamBYOBRequest.prototype, {\n  respond: { enumerable: true },\n  respondWithNewView: { enumerable: true },\n  view: { enumerable: true }\n});\nif (typeof Symbol.toStringTag === 'symbol') {\n  Object.defineProperty(ReadableStreamBYOBRequest.prototype, Symbol.toStringTag, {\n    value: 'ReadableStreamBYOBRequest',\n    configurable: true\n  });\n}\n\ninterface ArrayBufferViewConstructor {\n  new(buffer: ArrayBufferLike, byteOffset: number, length?: number): T;\n\n  readonly prototype: T;\n  readonly BYTES_PER_ELEMENT: number;\n}\n\ninterface ByteQueueElement {\n  buffer: ArrayBufferLike;\n  byteOffset: number;\n  byteLength: number;\n}\n\ntype PullIntoDescriptor =\n  DefaultPullIntoDescriptor\n  | BYOBPullIntoDescriptor;\n\ninterface DefaultPullIntoDescriptor {\n  buffer: ArrayBufferLike;\n  bufferByteLength: number;\n  byteOffset: number;\n  byteLength: number;\n  bytesFilled: number;\n  elementSize: number;\n  viewConstructor: ArrayBufferViewConstructor;\n  readerType: 'default';\n}\n\ninterface BYOBPullIntoDescriptor {\n  buffer: ArrayBufferLike;\n  bufferByteLength: number;\n  byteOffset: number;\n  byteLength: number;\n  bytesFilled: number;\n  elementSize: number;\n  viewConstructor: ArrayBufferViewConstructor;\n  readerType: 'byob';\n}\n\n/**\n * Allows control of a {@link ReadableStream | readable byte stream}'s state and internal queue.\n *\n * @public\n */\nexport class ReadableByteStreamController {\n  /** @internal */\n  _controlledReadableByteStream!: ReadableByteStream;\n  /** @internal */\n  _queue!: SimpleQueue;\n  /** @internal */\n  _queueTotalSize!: number;\n  /** @internal */\n  _started!: boolean;\n  /** @internal */\n  _closeRequested!: boolean;\n  /** @internal */\n  _pullAgain!: boolean;\n  /** @internal */\n  _pulling !: boolean;\n  /** @internal */\n  _strategyHWM!: number;\n  /** @internal */\n  _pullAlgorithm!: () => Promise;\n  /** @internal */\n  _cancelAlgorithm!: (reason: any) => Promise;\n  /** @internal */\n  _autoAllocateChunkSize: number | undefined;\n  /** @internal */\n  _byobRequest: ReadableStreamBYOBRequest | null;\n  /** @internal */\n  _pendingPullIntos!: SimpleQueue;\n\n  private constructor() {\n    throw new TypeError('Illegal constructor');\n  }\n\n  /**\n   * Returns the current BYOB pull request, or `null` if there isn't one.\n   */\n  get byobRequest(): ReadableStreamBYOBRequest | null {\n    if (!IsReadableByteStreamController(this)) {\n      throw byteStreamControllerBrandCheckException('byobRequest');\n    }\n\n    return ReadableByteStreamControllerGetBYOBRequest(this);\n  }\n\n  /**\n   * Returns the desired size to fill the controlled stream's internal queue. It can be negative, if the queue is\n   * over-full. An underlying byte source ought to use this information to determine when and how to apply backpressure.\n   */\n  get desiredSize(): number | null {\n    if (!IsReadableByteStreamController(this)) {\n      throw byteStreamControllerBrandCheckException('desiredSize');\n    }\n\n    return ReadableByteStreamControllerGetDesiredSize(this);\n  }\n\n  /**\n   * Closes the controlled readable stream. Consumers will still be able to read any previously-enqueued chunks from\n   * the stream, but once those are read, the stream will become closed.\n   */\n  close(): void {\n    if (!IsReadableByteStreamController(this)) {\n      throw byteStreamControllerBrandCheckException('close');\n    }\n\n    if (this._closeRequested) {\n      throw new TypeError('The stream has already been closed; do not close it again!');\n    }\n\n    const state = this._controlledReadableByteStream._state;\n    if (state !== 'readable') {\n      throw new TypeError(`The stream (in ${state} state) is not in the readable state and cannot be closed`);\n    }\n\n    ReadableByteStreamControllerClose(this);\n  }\n\n  /**\n   * Enqueues the given chunk chunk in the controlled readable stream.\n   * The chunk has to be an `ArrayBufferView` instance, or else a `TypeError` will be thrown.\n   */\n  enqueue(chunk: ArrayBufferView): void;\n  enqueue(chunk: ArrayBufferView | undefined): void {\n    if (!IsReadableByteStreamController(this)) {\n      throw byteStreamControllerBrandCheckException('enqueue');\n    }\n\n    assertRequiredArgument(chunk, 1, 'enqueue');\n    if (!ArrayBuffer.isView(chunk)) {\n      throw new TypeError('chunk must be an array buffer view');\n    }\n    if (chunk.byteLength === 0) {\n      throw new TypeError('chunk must have non-zero byteLength');\n    }\n    if (chunk.buffer.byteLength === 0) {\n      throw new TypeError(`chunk's buffer must have non-zero byteLength`);\n    }\n\n    if (this._closeRequested) {\n      throw new TypeError('stream is closed or draining');\n    }\n\n    const state = this._controlledReadableByteStream._state;\n    if (state !== 'readable') {\n      throw new TypeError(`The stream (in ${state} state) is not in the readable state and cannot be enqueued to`);\n    }\n\n    ReadableByteStreamControllerEnqueue(this, chunk);\n  }\n\n  /**\n   * Errors the controlled readable stream, making all future interactions with it fail with the given error `e`.\n   */\n  error(e: any = undefined): void {\n    if (!IsReadableByteStreamController(this)) {\n      throw byteStreamControllerBrandCheckException('error');\n    }\n\n    ReadableByteStreamControllerError(this, e);\n  }\n\n  /** @internal */\n  [CancelSteps](reason: any): Promise {\n    ReadableByteStreamControllerClearPendingPullIntos(this);\n\n    ResetQueue(this);\n\n    const result = this._cancelAlgorithm(reason);\n    ReadableByteStreamControllerClearAlgorithms(this);\n    return result;\n  }\n\n  /** @internal */\n  [PullSteps](readRequest: ReadRequest): void {\n    const stream = this._controlledReadableByteStream;\n    assert(ReadableStreamHasDefaultReader(stream));\n\n    if (this._queueTotalSize > 0) {\n      assert(ReadableStreamGetNumReadRequests(stream) === 0);\n\n      const entry = this._queue.shift()!;\n      this._queueTotalSize -= entry.byteLength;\n\n      ReadableByteStreamControllerHandleQueueDrain(this);\n\n      const view = new Uint8Array(entry.buffer, entry.byteOffset, entry.byteLength);\n\n      readRequest._chunkSteps(view);\n      return;\n    }\n\n    const autoAllocateChunkSize = this._autoAllocateChunkSize;\n    if (autoAllocateChunkSize !== undefined) {\n      let buffer: ArrayBuffer;\n      try {\n        buffer = new ArrayBuffer(autoAllocateChunkSize);\n      } catch (bufferE) {\n        readRequest._errorSteps(bufferE);\n        return;\n      }\n\n      const pullIntoDescriptor: DefaultPullIntoDescriptor = {\n        buffer,\n        bufferByteLength: autoAllocateChunkSize,\n        byteOffset: 0,\n        byteLength: autoAllocateChunkSize,\n        bytesFilled: 0,\n        elementSize: 1,\n        viewConstructor: Uint8Array,\n        readerType: 'default'\n      };\n\n      this._pendingPullIntos.push(pullIntoDescriptor);\n    }\n\n    ReadableStreamAddReadRequest(stream, readRequest);\n    ReadableByteStreamControllerCallPullIfNeeded(this);\n  }\n}\n\nObject.defineProperties(ReadableByteStreamController.prototype, {\n  close: { enumerable: true },\n  enqueue: { enumerable: true },\n  error: { enumerable: true },\n  byobRequest: { enumerable: true },\n  desiredSize: { enumerable: true }\n});\nif (typeof Symbol.toStringTag === 'symbol') {\n  Object.defineProperty(ReadableByteStreamController.prototype, Symbol.toStringTag, {\n    value: 'ReadableByteStreamController',\n    configurable: true\n  });\n}\n\n// Abstract operations for the ReadableByteStreamController.\n\nexport function IsReadableByteStreamController(x: any): x is ReadableByteStreamController {\n  if (!typeIsObject(x)) {\n    return false;\n  }\n\n  if (!Object.prototype.hasOwnProperty.call(x, '_controlledReadableByteStream')) {\n    return false;\n  }\n\n  return x instanceof ReadableByteStreamController;\n}\n\nfunction IsReadableStreamBYOBRequest(x: any): x is ReadableStreamBYOBRequest {\n  if (!typeIsObject(x)) {\n    return false;\n  }\n\n  if (!Object.prototype.hasOwnProperty.call(x, '_associatedReadableByteStreamController')) {\n    return false;\n  }\n\n  return x instanceof ReadableStreamBYOBRequest;\n}\n\nfunction ReadableByteStreamControllerCallPullIfNeeded(controller: ReadableByteStreamController): void {\n  const shouldPull = ReadableByteStreamControllerShouldCallPull(controller);\n  if (!shouldPull) {\n    return;\n  }\n\n  if (controller._pulling) {\n    controller._pullAgain = true;\n    return;\n  }\n\n  assert(!controller._pullAgain);\n\n  controller._pulling = true;\n\n  // TODO: Test controller argument\n  const pullPromise = controller._pullAlgorithm();\n  uponPromise(\n    pullPromise,\n    () => {\n      controller._pulling = false;\n\n      if (controller._pullAgain) {\n        controller._pullAgain = false;\n        ReadableByteStreamControllerCallPullIfNeeded(controller);\n      }\n    },\n    e => {\n      ReadableByteStreamControllerError(controller, e);\n    }\n  );\n}\n\nfunction ReadableByteStreamControllerClearPendingPullIntos(controller: ReadableByteStreamController) {\n  ReadableByteStreamControllerInvalidateBYOBRequest(controller);\n  controller._pendingPullIntos = new SimpleQueue();\n}\n\nfunction ReadableByteStreamControllerCommitPullIntoDescriptor(\n  stream: ReadableByteStream,\n  pullIntoDescriptor: PullIntoDescriptor\n) {\n  assert(stream._state !== 'errored');\n\n  let done = false;\n  if (stream._state === 'closed') {\n    assert(pullIntoDescriptor.bytesFilled === 0);\n    done = true;\n  }\n\n  const filledView = ReadableByteStreamControllerConvertPullIntoDescriptor(pullIntoDescriptor);\n  if (pullIntoDescriptor.readerType === 'default') {\n    ReadableStreamFulfillReadRequest(stream, filledView as unknown as Uint8Array, done);\n  } else {\n    assert(pullIntoDescriptor.readerType === 'byob');\n    ReadableStreamFulfillReadIntoRequest(stream, filledView, done);\n  }\n}\n\nfunction ReadableByteStreamControllerConvertPullIntoDescriptor(\n  pullIntoDescriptor: PullIntoDescriptor\n): T {\n  const bytesFilled = pullIntoDescriptor.bytesFilled;\n  const elementSize = pullIntoDescriptor.elementSize;\n\n  assert(bytesFilled <= pullIntoDescriptor.byteLength);\n  assert(bytesFilled % elementSize === 0);\n\n  return new pullIntoDescriptor.viewConstructor(\n    pullIntoDescriptor.buffer, pullIntoDescriptor.byteOffset, bytesFilled / elementSize) as T;\n}\n\nfunction ReadableByteStreamControllerEnqueueChunkToQueue(controller: ReadableByteStreamController,\n                                                         buffer: ArrayBufferLike,\n                                                         byteOffset: number,\n                                                         byteLength: number) {\n  controller._queue.push({ buffer, byteOffset, byteLength });\n  controller._queueTotalSize += byteLength;\n}\n\nfunction ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(controller: ReadableByteStreamController,\n                                                                     pullIntoDescriptor: PullIntoDescriptor) {\n  const elementSize = pullIntoDescriptor.elementSize;\n\n  const currentAlignedBytes = pullIntoDescriptor.bytesFilled - pullIntoDescriptor.bytesFilled % elementSize;\n\n  const maxBytesToCopy = Math.min(controller._queueTotalSize,\n                                  pullIntoDescriptor.byteLength - pullIntoDescriptor.bytesFilled);\n  const maxBytesFilled = pullIntoDescriptor.bytesFilled + maxBytesToCopy;\n  const maxAlignedBytes = maxBytesFilled - maxBytesFilled % elementSize;\n\n  let totalBytesToCopyRemaining = maxBytesToCopy;\n  let ready = false;\n  if (maxAlignedBytes > currentAlignedBytes) {\n    totalBytesToCopyRemaining = maxAlignedBytes - pullIntoDescriptor.bytesFilled;\n    ready = true;\n  }\n\n  const queue = controller._queue;\n\n  while (totalBytesToCopyRemaining > 0) {\n    const headOfQueue = queue.peek();\n\n    const bytesToCopy = Math.min(totalBytesToCopyRemaining, headOfQueue.byteLength);\n\n    const destStart = pullIntoDescriptor.byteOffset + pullIntoDescriptor.bytesFilled;\n    CopyDataBlockBytes(pullIntoDescriptor.buffer, destStart, headOfQueue.buffer, headOfQueue.byteOffset, bytesToCopy);\n\n    if (headOfQueue.byteLength === bytesToCopy) {\n      queue.shift();\n    } else {\n      headOfQueue.byteOffset += bytesToCopy;\n      headOfQueue.byteLength -= bytesToCopy;\n    }\n    controller._queueTotalSize -= bytesToCopy;\n\n    ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller, bytesToCopy, pullIntoDescriptor);\n\n    totalBytesToCopyRemaining -= bytesToCopy;\n  }\n\n  if (!ready) {\n    assert(controller._queueTotalSize === 0);\n    assert(pullIntoDescriptor.bytesFilled > 0);\n    assert(pullIntoDescriptor.bytesFilled < pullIntoDescriptor.elementSize);\n  }\n\n  return ready;\n}\n\nfunction ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller: ReadableByteStreamController,\n                                                                size: number,\n                                                                pullIntoDescriptor: PullIntoDescriptor) {\n  assert(controller._pendingPullIntos.length === 0 || controller._pendingPullIntos.peek() === pullIntoDescriptor);\n  assert(controller._byobRequest === null);\n  pullIntoDescriptor.bytesFilled += size;\n}\n\nfunction ReadableByteStreamControllerHandleQueueDrain(controller: ReadableByteStreamController) {\n  assert(controller._controlledReadableByteStream._state === 'readable');\n\n  if (controller._queueTotalSize === 0 && controller._closeRequested) {\n    ReadableByteStreamControllerClearAlgorithms(controller);\n    ReadableStreamClose(controller._controlledReadableByteStream);\n  } else {\n    ReadableByteStreamControllerCallPullIfNeeded(controller);\n  }\n}\n\nfunction ReadableByteStreamControllerInvalidateBYOBRequest(controller: ReadableByteStreamController) {\n  if (controller._byobRequest === null) {\n    return;\n  }\n\n  controller._byobRequest._associatedReadableByteStreamController = undefined!;\n  controller._byobRequest._view = null!;\n  controller._byobRequest = null;\n}\n\nfunction ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller: ReadableByteStreamController) {\n  assert(!controller._closeRequested);\n\n  while (controller._pendingPullIntos.length > 0) {\n    if (controller._queueTotalSize === 0) {\n      return;\n    }\n\n    const pullIntoDescriptor = controller._pendingPullIntos.peek();\n\n    if (ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(controller, pullIntoDescriptor)) {\n      ReadableByteStreamControllerShiftPendingPullInto(controller);\n\n      ReadableByteStreamControllerCommitPullIntoDescriptor(\n        controller._controlledReadableByteStream,\n        pullIntoDescriptor\n      );\n    }\n  }\n}\n\nexport function ReadableByteStreamControllerPullInto(\n  controller: ReadableByteStreamController,\n  view: T,\n  readIntoRequest: ReadIntoRequest\n): void {\n  const stream = controller._controlledReadableByteStream;\n\n  let elementSize = 1;\n  if (view.constructor !== DataView) {\n    elementSize = (view.constructor as ArrayBufferViewConstructor).BYTES_PER_ELEMENT;\n  }\n\n  const ctor = view.constructor as ArrayBufferViewConstructor;\n\n  // try {\n  const buffer = TransferArrayBuffer(view.buffer);\n  // } catch (e) {\n  //   readIntoRequest._errorSteps(e);\n  //   return;\n  // }\n\n  const pullIntoDescriptor: BYOBPullIntoDescriptor = {\n    buffer,\n    bufferByteLength: buffer.byteLength,\n    byteOffset: view.byteOffset,\n    byteLength: view.byteLength,\n    bytesFilled: 0,\n    elementSize,\n    viewConstructor: ctor,\n    readerType: 'byob'\n  };\n\n  if (controller._pendingPullIntos.length > 0) {\n    controller._pendingPullIntos.push(pullIntoDescriptor);\n\n    // No ReadableByteStreamControllerCallPullIfNeeded() call since:\n    // - No change happens on desiredSize\n    // - The source has already been notified of that there's at least 1 pending read(view)\n\n    ReadableStreamAddReadIntoRequest(stream, readIntoRequest);\n    return;\n  }\n\n  if (stream._state === 'closed') {\n    const emptyView = new ctor(pullIntoDescriptor.buffer, pullIntoDescriptor.byteOffset, 0);\n    readIntoRequest._closeSteps(emptyView);\n    return;\n  }\n\n  if (controller._queueTotalSize > 0) {\n    if (ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(controller, pullIntoDescriptor)) {\n      const filledView = ReadableByteStreamControllerConvertPullIntoDescriptor(pullIntoDescriptor);\n\n      ReadableByteStreamControllerHandleQueueDrain(controller);\n\n      readIntoRequest._chunkSteps(filledView);\n      return;\n    }\n\n    if (controller._closeRequested) {\n      const e = new TypeError('Insufficient bytes to fill elements in the given buffer');\n      ReadableByteStreamControllerError(controller, e);\n\n      readIntoRequest._errorSteps(e);\n      return;\n    }\n  }\n\n  controller._pendingPullIntos.push(pullIntoDescriptor);\n\n  ReadableStreamAddReadIntoRequest(stream, readIntoRequest);\n  ReadableByteStreamControllerCallPullIfNeeded(controller);\n}\n\nfunction ReadableByteStreamControllerRespondInClosedState(controller: ReadableByteStreamController,\n                                                          firstDescriptor: PullIntoDescriptor) {\n  assert(firstDescriptor.bytesFilled === 0);\n\n  const stream = controller._controlledReadableByteStream;\n  if (ReadableStreamHasBYOBReader(stream)) {\n    while (ReadableStreamGetNumReadIntoRequests(stream) > 0) {\n      const pullIntoDescriptor = ReadableByteStreamControllerShiftPendingPullInto(controller);\n      ReadableByteStreamControllerCommitPullIntoDescriptor(stream, pullIntoDescriptor);\n    }\n  }\n}\n\nfunction ReadableByteStreamControllerRespondInReadableState(controller: ReadableByteStreamController,\n                                                            bytesWritten: number,\n                                                            pullIntoDescriptor: PullIntoDescriptor) {\n  assert(pullIntoDescriptor.bytesFilled + bytesWritten <= pullIntoDescriptor.byteLength);\n\n  ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller, bytesWritten, pullIntoDescriptor);\n\n  if (pullIntoDescriptor.bytesFilled < pullIntoDescriptor.elementSize) {\n    return;\n  }\n\n  ReadableByteStreamControllerShiftPendingPullInto(controller);\n\n  const remainderSize = pullIntoDescriptor.bytesFilled % pullIntoDescriptor.elementSize;\n  if (remainderSize > 0) {\n    const end = pullIntoDescriptor.byteOffset + pullIntoDescriptor.bytesFilled;\n    const remainder = ArrayBufferSlice(pullIntoDescriptor.buffer, end - remainderSize, end);\n    ReadableByteStreamControllerEnqueueChunkToQueue(controller, remainder, 0, remainder.byteLength);\n  }\n\n  pullIntoDescriptor.bytesFilled -= remainderSize;\n  ReadableByteStreamControllerCommitPullIntoDescriptor(controller._controlledReadableByteStream, pullIntoDescriptor);\n\n  ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller);\n}\n\nfunction ReadableByteStreamControllerRespondInternal(controller: ReadableByteStreamController, bytesWritten: number) {\n  const firstDescriptor = controller._pendingPullIntos.peek();\n  assert(CanTransferArrayBuffer(firstDescriptor.buffer));\n\n  ReadableByteStreamControllerInvalidateBYOBRequest(controller);\n\n  const state = controller._controlledReadableByteStream._state;\n  if (state === 'closed') {\n    assert(bytesWritten === 0);\n    ReadableByteStreamControllerRespondInClosedState(controller, firstDescriptor);\n  } else {\n    assert(state === 'readable');\n    assert(bytesWritten > 0);\n    ReadableByteStreamControllerRespondInReadableState(controller, bytesWritten, firstDescriptor);\n  }\n\n  ReadableByteStreamControllerCallPullIfNeeded(controller);\n}\n\nfunction ReadableByteStreamControllerShiftPendingPullInto(\n  controller: ReadableByteStreamController\n): PullIntoDescriptor {\n  assert(controller._byobRequest === null);\n  const descriptor = controller._pendingPullIntos.shift()!;\n  return descriptor;\n}\n\nfunction ReadableByteStreamControllerShouldCallPull(controller: ReadableByteStreamController): boolean {\n  const stream = controller._controlledReadableByteStream;\n\n  if (stream._state !== 'readable') {\n    return false;\n  }\n\n  if (controller._closeRequested) {\n    return false;\n  }\n\n  if (!controller._started) {\n    return false;\n  }\n\n  if (ReadableStreamHasDefaultReader(stream) && ReadableStreamGetNumReadRequests(stream) > 0) {\n    return true;\n  }\n\n  if (ReadableStreamHasBYOBReader(stream) && ReadableStreamGetNumReadIntoRequests(stream) > 0) {\n    return true;\n  }\n\n  const desiredSize = ReadableByteStreamControllerGetDesiredSize(controller);\n  assert(desiredSize !== null);\n  if (desiredSize! > 0) {\n    return true;\n  }\n\n  return false;\n}\n\nfunction ReadableByteStreamControllerClearAlgorithms(controller: ReadableByteStreamController) {\n  controller._pullAlgorithm = undefined!;\n  controller._cancelAlgorithm = undefined!;\n}\n\n// A client of ReadableByteStreamController may use these functions directly to bypass state check.\n\nexport function ReadableByteStreamControllerClose(controller: ReadableByteStreamController) {\n  const stream = controller._controlledReadableByteStream;\n\n  if (controller._closeRequested || stream._state !== 'readable') {\n    return;\n  }\n\n  if (controller._queueTotalSize > 0) {\n    controller._closeRequested = true;\n\n    return;\n  }\n\n  if (controller._pendingPullIntos.length > 0) {\n    const firstPendingPullInto = controller._pendingPullIntos.peek();\n    if (firstPendingPullInto.bytesFilled > 0) {\n      const e = new TypeError('Insufficient bytes to fill elements in the given buffer');\n      ReadableByteStreamControllerError(controller, e);\n\n      throw e;\n    }\n  }\n\n  ReadableByteStreamControllerClearAlgorithms(controller);\n  ReadableStreamClose(stream);\n}\n\nexport function ReadableByteStreamControllerEnqueue(controller: ReadableByteStreamController, chunk: ArrayBufferView) {\n  const stream = controller._controlledReadableByteStream;\n\n  if (controller._closeRequested || stream._state !== 'readable') {\n    return;\n  }\n\n  const buffer = chunk.buffer;\n  const byteOffset = chunk.byteOffset;\n  const byteLength = chunk.byteLength;\n  if (IsDetachedBuffer(buffer)) {\n    throw new TypeError('chunk\\'s buffer is detached and so cannot be enqueued');\n  }\n  const transferredBuffer = TransferArrayBuffer(buffer);\n\n  if (controller._pendingPullIntos.length > 0) {\n    const firstPendingPullInto = controller._pendingPullIntos.peek();\n    if (IsDetachedBuffer(firstPendingPullInto.buffer)) {\n      throw new TypeError(\n        'The BYOB request\\'s buffer has been detached and so cannot be filled with an enqueued chunk'\n      );\n    }\n    firstPendingPullInto.buffer = TransferArrayBuffer(firstPendingPullInto.buffer);\n  }\n\n  ReadableByteStreamControllerInvalidateBYOBRequest(controller);\n\n  if (ReadableStreamHasDefaultReader(stream)) {\n    if (ReadableStreamGetNumReadRequests(stream) === 0) {\n      assert(controller._pendingPullIntos.length === 0);\n      ReadableByteStreamControllerEnqueueChunkToQueue(controller, transferredBuffer, byteOffset, byteLength);\n    } else {\n      assert(controller._queue.length === 0);\n      if (controller._pendingPullIntos.length > 0) {\n        assert(controller._pendingPullIntos.peek().readerType === 'default');\n        ReadableByteStreamControllerShiftPendingPullInto(controller);\n      }\n      const transferredView = new Uint8Array(transferredBuffer, byteOffset, byteLength);\n      ReadableStreamFulfillReadRequest(stream, transferredView, false);\n    }\n  } else if (ReadableStreamHasBYOBReader(stream)) {\n    // TODO: Ideally in this branch detaching should happen only if the buffer is not consumed fully.\n    ReadableByteStreamControllerEnqueueChunkToQueue(controller, transferredBuffer, byteOffset, byteLength);\n    ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller);\n  } else {\n    assert(!IsReadableStreamLocked(stream));\n    ReadableByteStreamControllerEnqueueChunkToQueue(controller, transferredBuffer, byteOffset, byteLength);\n  }\n\n  ReadableByteStreamControllerCallPullIfNeeded(controller);\n}\n\nexport function ReadableByteStreamControllerError(controller: ReadableByteStreamController, e: any) {\n  const stream = controller._controlledReadableByteStream;\n\n  if (stream._state !== 'readable') {\n    return;\n  }\n\n  ReadableByteStreamControllerClearPendingPullIntos(controller);\n\n  ResetQueue(controller);\n  ReadableByteStreamControllerClearAlgorithms(controller);\n  ReadableStreamError(stream, e);\n}\n\nexport function ReadableByteStreamControllerGetBYOBRequest(\n  controller: ReadableByteStreamController\n): ReadableStreamBYOBRequest | null {\n  if (controller._byobRequest === null && controller._pendingPullIntos.length > 0) {\n    const firstDescriptor = controller._pendingPullIntos.peek();\n    const view = new Uint8Array(firstDescriptor.buffer,\n                                firstDescriptor.byteOffset + firstDescriptor.bytesFilled,\n                                firstDescriptor.byteLength - firstDescriptor.bytesFilled);\n\n    const byobRequest: ReadableStreamBYOBRequest = Object.create(ReadableStreamBYOBRequest.prototype);\n    SetUpReadableStreamBYOBRequest(byobRequest, controller, view);\n    controller._byobRequest = byobRequest;\n  }\n  return controller._byobRequest;\n}\n\nfunction ReadableByteStreamControllerGetDesiredSize(controller: ReadableByteStreamController): number | null {\n  const state = controller._controlledReadableByteStream._state;\n\n  if (state === 'errored') {\n    return null;\n  }\n  if (state === 'closed') {\n    return 0;\n  }\n\n  return controller._strategyHWM - controller._queueTotalSize;\n}\n\nexport function ReadableByteStreamControllerRespond(controller: ReadableByteStreamController, bytesWritten: number) {\n  assert(controller._pendingPullIntos.length > 0);\n\n  const firstDescriptor = controller._pendingPullIntos.peek();\n  const state = controller._controlledReadableByteStream._state;\n\n  if (state === 'closed') {\n    if (bytesWritten !== 0) {\n      throw new TypeError('bytesWritten must be 0 when calling respond() on a closed stream');\n    }\n  } else {\n    assert(state === 'readable');\n    if (bytesWritten === 0) {\n      throw new TypeError('bytesWritten must be greater than 0 when calling respond() on a readable stream');\n    }\n    if (firstDescriptor.bytesFilled + bytesWritten > firstDescriptor.byteLength) {\n      throw new RangeError('bytesWritten out of range');\n    }\n  }\n\n  firstDescriptor.buffer = TransferArrayBuffer(firstDescriptor.buffer);\n\n  ReadableByteStreamControllerRespondInternal(controller, bytesWritten);\n}\n\nexport function ReadableByteStreamControllerRespondWithNewView(controller: ReadableByteStreamController,\n                                                               view: ArrayBufferView) {\n  assert(controller._pendingPullIntos.length > 0);\n  assert(!IsDetachedBuffer(view.buffer));\n\n  const firstDescriptor = controller._pendingPullIntos.peek();\n  const state = controller._controlledReadableByteStream._state;\n\n  if (state === 'closed') {\n    if (view.byteLength !== 0) {\n      throw new TypeError('The view\\'s length must be 0 when calling respondWithNewView() on a closed stream');\n    }\n  } else {\n    assert(state === 'readable');\n    if (view.byteLength === 0) {\n      throw new TypeError(\n        'The view\\'s length must be greater than 0 when calling respondWithNewView() on a readable stream'\n      );\n    }\n  }\n\n  if (firstDescriptor.byteOffset + firstDescriptor.bytesFilled !== view.byteOffset) {\n    throw new RangeError('The region specified by view does not match byobRequest');\n  }\n  if (firstDescriptor.bufferByteLength !== view.buffer.byteLength) {\n    throw new RangeError('The buffer of view has different capacity than byobRequest');\n  }\n  if (firstDescriptor.bytesFilled + view.byteLength > firstDescriptor.byteLength) {\n    throw new RangeError('The region specified by view is larger than byobRequest');\n  }\n\n  const viewByteLength = view.byteLength;\n  firstDescriptor.buffer = TransferArrayBuffer(view.buffer);\n  ReadableByteStreamControllerRespondInternal(controller, viewByteLength);\n}\n\nexport function SetUpReadableByteStreamController(stream: ReadableByteStream,\n                                                  controller: ReadableByteStreamController,\n                                                  startAlgorithm: () => void | PromiseLike,\n                                                  pullAlgorithm: () => Promise,\n                                                  cancelAlgorithm: (reason: any) => Promise,\n                                                  highWaterMark: number,\n                                                  autoAllocateChunkSize: number | undefined) {\n  assert(stream._readableStreamController === undefined);\n  if (autoAllocateChunkSize !== undefined) {\n    assert(NumberIsInteger(autoAllocateChunkSize));\n    assert(autoAllocateChunkSize > 0);\n  }\n\n  controller._controlledReadableByteStream = stream;\n\n  controller._pullAgain = false;\n  controller._pulling = false;\n\n  controller._byobRequest = null;\n\n  // Need to set the slots so that the assert doesn't fire. In the spec the slots already exist implicitly.\n  controller._queue = controller._queueTotalSize = undefined!;\n  ResetQueue(controller);\n\n  controller._closeRequested = false;\n  controller._started = false;\n\n  controller._strategyHWM = highWaterMark;\n\n  controller._pullAlgorithm = pullAlgorithm;\n  controller._cancelAlgorithm = cancelAlgorithm;\n\n  controller._autoAllocateChunkSize = autoAllocateChunkSize;\n\n  controller._pendingPullIntos = new SimpleQueue();\n\n  stream._readableStreamController = controller;\n\n  const startResult = startAlgorithm();\n  uponPromise(\n    promiseResolvedWith(startResult),\n    () => {\n      controller._started = true;\n\n      assert(!controller._pulling);\n      assert(!controller._pullAgain);\n\n      ReadableByteStreamControllerCallPullIfNeeded(controller);\n    },\n    r => {\n      ReadableByteStreamControllerError(controller, r);\n    }\n  );\n}\n\nexport function SetUpReadableByteStreamControllerFromUnderlyingSource(\n  stream: ReadableByteStream,\n  underlyingByteSource: ValidatedUnderlyingByteSource,\n  highWaterMark: number\n) {\n  const controller: ReadableByteStreamController = Object.create(ReadableByteStreamController.prototype);\n\n  let startAlgorithm: () => void | PromiseLike = () => undefined;\n  let pullAlgorithm: () => Promise = () => promiseResolvedWith(undefined);\n  let cancelAlgorithm: (reason: any) => Promise = () => promiseResolvedWith(undefined);\n\n  if (underlyingByteSource.start !== undefined) {\n    startAlgorithm = () => underlyingByteSource.start!(controller);\n  }\n  if (underlyingByteSource.pull !== undefined) {\n    pullAlgorithm = () => underlyingByteSource.pull!(controller);\n  }\n  if (underlyingByteSource.cancel !== undefined) {\n    cancelAlgorithm = reason => underlyingByteSource.cancel!(reason);\n  }\n\n  const autoAllocateChunkSize = underlyingByteSource.autoAllocateChunkSize;\n  if (autoAllocateChunkSize === 0) {\n    throw new TypeError('autoAllocateChunkSize must be greater than 0');\n  }\n\n  SetUpReadableByteStreamController(\n    stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, autoAllocateChunkSize\n  );\n}\n\nfunction SetUpReadableStreamBYOBRequest(request: ReadableStreamBYOBRequest,\n                                        controller: ReadableByteStreamController,\n                                        view: ArrayBufferView) {\n  assert(IsReadableByteStreamController(controller));\n  assert(typeof view === 'object');\n  assert(ArrayBuffer.isView(view));\n  assert(!IsDetachedBuffer(view.buffer));\n  request._associatedReadableByteStreamController = controller;\n  request._view = view;\n}\n\n// Helper functions for the ReadableStreamBYOBRequest.\n\nfunction byobRequestBrandCheckException(name: string): TypeError {\n  return new TypeError(\n    `ReadableStreamBYOBRequest.prototype.${name} can only be used on a ReadableStreamBYOBRequest`);\n}\n\n// Helper functions for the ReadableByteStreamController.\n\nfunction byteStreamControllerBrandCheckException(name: string): TypeError {\n  return new TypeError(\n    `ReadableByteStreamController.prototype.${name} can only be used on a ReadableByteStreamController`);\n}\n","import assert from '../../stub/assert';\nimport { SimpleQueue } from '../simple-queue';\nimport {\n  ReadableStreamReaderGenericCancel,\n  ReadableStreamReaderGenericInitialize,\n  ReadableStreamReaderGenericRelease,\n  readerLockException\n} from './generic-reader';\nimport { IsReadableStreamLocked, ReadableByteStream, ReadableStream } from '../readable-stream';\nimport {\n  IsReadableByteStreamController,\n  ReadableByteStreamController,\n  ReadableByteStreamControllerPullInto\n} from './byte-stream-controller';\nimport { typeIsObject } from '../helpers/miscellaneous';\nimport { newPromise, promiseRejectedWith } from '../helpers/webidl';\nimport { assertRequiredArgument } from '../validators/basic';\nimport { assertReadableStream } from '../validators/readable-stream';\nimport { IsDetachedBuffer } from '../abstract-ops/ecmascript';\n\n/**\n * A result returned by {@link ReadableStreamBYOBReader.read}.\n *\n * @public\n */\nexport type ReadableStreamBYOBReadResult = {\n  done: false;\n  value: T;\n} | {\n  done: true;\n  value: T | undefined;\n};\n\n// Abstract operations for the ReadableStream.\n\nexport function AcquireReadableStreamBYOBReader(stream: ReadableByteStream): ReadableStreamBYOBReader {\n  return new ReadableStreamBYOBReader(stream);\n}\n\n// ReadableStream API exposed for controllers.\n\nexport function ReadableStreamAddReadIntoRequest(stream: ReadableByteStream,\n                                                                            readIntoRequest: ReadIntoRequest): void {\n  assert(IsReadableStreamBYOBReader(stream._reader));\n  assert(stream._state === 'readable' || stream._state === 'closed');\n\n  (stream._reader! as ReadableStreamBYOBReader)._readIntoRequests.push(readIntoRequest);\n}\n\nexport function ReadableStreamFulfillReadIntoRequest(stream: ReadableByteStream,\n                                                     chunk: ArrayBufferView,\n                                                     done: boolean) {\n  const reader = stream._reader as ReadableStreamBYOBReader;\n\n  assert(reader._readIntoRequests.length > 0);\n\n  const readIntoRequest = reader._readIntoRequests.shift()!;\n  if (done) {\n    readIntoRequest._closeSteps(chunk);\n  } else {\n    readIntoRequest._chunkSteps(chunk);\n  }\n}\n\nexport function ReadableStreamGetNumReadIntoRequests(stream: ReadableByteStream): number {\n  return (stream._reader as ReadableStreamBYOBReader)._readIntoRequests.length;\n}\n\nexport function ReadableStreamHasBYOBReader(stream: ReadableByteStream): boolean {\n  const reader = stream._reader;\n\n  if (reader === undefined) {\n    return false;\n  }\n\n  if (!IsReadableStreamBYOBReader(reader)) {\n    return false;\n  }\n\n  return true;\n}\n\n// Readers\n\nexport interface ReadIntoRequest {\n  _chunkSteps(chunk: T): void;\n\n  _closeSteps(chunk: T | undefined): void;\n\n  _errorSteps(e: any): void;\n}\n\n/**\n * A BYOB reader vended by a {@link ReadableStream}.\n *\n * @public\n */\nexport class ReadableStreamBYOBReader {\n  /** @internal */\n  _ownerReadableStream!: ReadableByteStream;\n  /** @internal */\n  _closedPromise!: Promise;\n  /** @internal */\n  _closedPromise_resolve?: (value?: undefined) => void;\n  /** @internal */\n  _closedPromise_reject?: (reason: any) => void;\n  /** @internal */\n  _readIntoRequests: SimpleQueue>;\n\n  constructor(stream: ReadableByteStream) {\n    assertRequiredArgument(stream, 1, 'ReadableStreamBYOBReader');\n    assertReadableStream(stream, 'First parameter');\n\n    if (IsReadableStreamLocked(stream)) {\n      throw new TypeError('This stream has already been locked for exclusive reading by another reader');\n    }\n\n    if (!IsReadableByteStreamController(stream._readableStreamController)) {\n      throw new TypeError('Cannot construct a ReadableStreamBYOBReader for a stream not constructed with a byte ' +\n        'source');\n    }\n\n    ReadableStreamReaderGenericInitialize(this, stream);\n\n    this._readIntoRequests = new SimpleQueue();\n  }\n\n  /**\n   * Returns a promise that will be fulfilled when the stream becomes closed, or rejected if the stream ever errors or\n   * the reader's lock is released before the stream finishes closing.\n   */\n  get closed(): Promise {\n    if (!IsReadableStreamBYOBReader(this)) {\n      return promiseRejectedWith(byobReaderBrandCheckException('closed'));\n    }\n\n    return this._closedPromise;\n  }\n\n  /**\n   * If the reader is active, behaves the same as {@link ReadableStream.cancel | stream.cancel(reason)}.\n   */\n  cancel(reason: any = undefined): Promise {\n    if (!IsReadableStreamBYOBReader(this)) {\n      return promiseRejectedWith(byobReaderBrandCheckException('cancel'));\n    }\n\n    if (this._ownerReadableStream === undefined) {\n      return promiseRejectedWith(readerLockException('cancel'));\n    }\n\n    return ReadableStreamReaderGenericCancel(this, reason);\n  }\n\n  /**\n   * Attempts to reads bytes into view, and returns a promise resolved with the result.\n   *\n   * If reading a chunk causes the queue to become empty, more data will be pulled from the underlying source.\n   */\n  read(view: T): Promise> {\n    if (!IsReadableStreamBYOBReader(this)) {\n      return promiseRejectedWith(byobReaderBrandCheckException('read'));\n    }\n\n    if (!ArrayBuffer.isView(view)) {\n      return promiseRejectedWith(new TypeError('view must be an array buffer view'));\n    }\n    if (view.byteLength === 0) {\n      return promiseRejectedWith(new TypeError('view must have non-zero byteLength'));\n    }\n    if (view.buffer.byteLength === 0) {\n      return promiseRejectedWith(new TypeError(`view's buffer must have non-zero byteLength`));\n    }\n    if (IsDetachedBuffer(view.buffer)) {\n      return promiseRejectedWith(new TypeError('view\\'s buffer has been detached'));\n    }\n\n    if (this._ownerReadableStream === undefined) {\n      return promiseRejectedWith(readerLockException('read from'));\n    }\n\n    let resolvePromise!: (result: ReadableStreamBYOBReadResult) => void;\n    let rejectPromise!: (reason: any) => void;\n    const promise = newPromise>((resolve, reject) => {\n      resolvePromise = resolve;\n      rejectPromise = reject;\n    });\n    const readIntoRequest: ReadIntoRequest = {\n      _chunkSteps: chunk => resolvePromise({ value: chunk, done: false }),\n      _closeSteps: chunk => resolvePromise({ value: chunk, done: true }),\n      _errorSteps: e => rejectPromise(e)\n    };\n    ReadableStreamBYOBReaderRead(this, view, readIntoRequest);\n    return promise;\n  }\n\n  /**\n   * Releases the reader's lock on the corresponding stream. After the lock is released, the reader is no longer active.\n   * If the associated stream is errored when the lock is released, the reader will appear errored in the same way\n   * from now on; otherwise, the reader will appear closed.\n   *\n   * A reader's lock cannot be released while it still has a pending read request, i.e., if a promise returned by\n   * the reader's {@link ReadableStreamBYOBReader.read | read()} method has not yet been settled. Attempting to\n   * do so will throw a `TypeError` and leave the reader locked to the stream.\n   */\n  releaseLock(): void {\n    if (!IsReadableStreamBYOBReader(this)) {\n      throw byobReaderBrandCheckException('releaseLock');\n    }\n\n    if (this._ownerReadableStream === undefined) {\n      return;\n    }\n\n    if (this._readIntoRequests.length > 0) {\n      throw new TypeError('Tried to release a reader lock when that reader has pending read() calls un-settled');\n    }\n\n    ReadableStreamReaderGenericRelease(this);\n  }\n}\n\nObject.defineProperties(ReadableStreamBYOBReader.prototype, {\n  cancel: { enumerable: true },\n  read: { enumerable: true },\n  releaseLock: { enumerable: true },\n  closed: { enumerable: true }\n});\nif (typeof Symbol.toStringTag === 'symbol') {\n  Object.defineProperty(ReadableStreamBYOBReader.prototype, Symbol.toStringTag, {\n    value: 'ReadableStreamBYOBReader',\n    configurable: true\n  });\n}\n\n// Abstract operations for the readers.\n\nexport function IsReadableStreamBYOBReader(x: any): x is ReadableStreamBYOBReader {\n  if (!typeIsObject(x)) {\n    return false;\n  }\n\n  if (!Object.prototype.hasOwnProperty.call(x, '_readIntoRequests')) {\n    return false;\n  }\n\n  return x instanceof ReadableStreamBYOBReader;\n}\n\nexport function ReadableStreamBYOBReaderRead(\n  reader: ReadableStreamBYOBReader,\n  view: T,\n  readIntoRequest: ReadIntoRequest\n): void {\n  const stream = reader._ownerReadableStream;\n\n  assert(stream !== undefined);\n\n  stream._disturbed = true;\n\n  if (stream._state === 'errored') {\n    readIntoRequest._errorSteps(stream._storedError);\n  } else {\n    ReadableByteStreamControllerPullInto(\n      stream._readableStreamController as ReadableByteStreamController,\n      view,\n      readIntoRequest\n    );\n  }\n}\n\n// Helper functions for the ReadableStreamBYOBReader.\n\nfunction byobReaderBrandCheckException(name: string): TypeError {\n  return new TypeError(\n    `ReadableStreamBYOBReader.prototype.${name} can only be used on a ReadableStreamBYOBReader`);\n}\n","import { QueuingStrategy, QueuingStrategySizeCallback } from '../queuing-strategy';\nimport NumberIsNaN from '../../stub/number-isnan';\n\nexport function ExtractHighWaterMark(strategy: QueuingStrategy, defaultHWM: number): number {\n  const { highWaterMark } = strategy;\n\n  if (highWaterMark === undefined) {\n    return defaultHWM;\n  }\n\n  if (NumberIsNaN(highWaterMark) || highWaterMark < 0) {\n    throw new RangeError('Invalid highWaterMark');\n  }\n\n  return highWaterMark;\n}\n\nexport function ExtractSizeAlgorithm(strategy: QueuingStrategy): QueuingStrategySizeCallback {\n  const { size } = strategy;\n\n  if (!size) {\n    return () => 1;\n  }\n\n  return size;\n}\n","import { QueuingStrategy, QueuingStrategySizeCallback } from '../queuing-strategy';\nimport { assertDictionary, assertFunction, convertUnrestrictedDouble } from './basic';\n\nexport function convertQueuingStrategy(init: QueuingStrategy | null | undefined,\n                                          context: string): QueuingStrategy {\n  assertDictionary(init, context);\n  const highWaterMark = init?.highWaterMark;\n  const size = init?.size;\n  return {\n    highWaterMark: highWaterMark === undefined ? undefined : convertUnrestrictedDouble(highWaterMark),\n    size: size === undefined ? undefined : convertQueuingStrategySize(size, `${context} has member 'size' that`)\n  };\n}\n\nfunction convertQueuingStrategySize(fn: QueuingStrategySizeCallback,\n                                       context: string): QueuingStrategySizeCallback {\n  assertFunction(fn, context);\n  return chunk => convertUnrestrictedDouble(fn(chunk));\n}\n","import { assertDictionary, assertFunction } from './basic';\nimport { promiseCall, reflectCall } from '../helpers/webidl';\nimport {\n  UnderlyingSink,\n  UnderlyingSinkAbortCallback,\n  UnderlyingSinkCloseCallback,\n  UnderlyingSinkStartCallback,\n  UnderlyingSinkWriteCallback,\n  ValidatedUnderlyingSink\n} from '../writable-stream/underlying-sink';\nimport { WritableStreamDefaultController } from '../writable-stream';\n\nexport function convertUnderlyingSink(original: UnderlyingSink | null,\n                                         context: string): ValidatedUnderlyingSink {\n  assertDictionary(original, context);\n  const abort = original?.abort;\n  const close = original?.close;\n  const start = original?.start;\n  const type = original?.type;\n  const write = original?.write;\n  return {\n    abort: abort === undefined ?\n      undefined :\n      convertUnderlyingSinkAbortCallback(abort, original!, `${context} has member 'abort' that`),\n    close: close === undefined ?\n      undefined :\n      convertUnderlyingSinkCloseCallback(close, original!, `${context} has member 'close' that`),\n    start: start === undefined ?\n      undefined :\n      convertUnderlyingSinkStartCallback(start, original!, `${context} has member 'start' that`),\n    write: write === undefined ?\n      undefined :\n      convertUnderlyingSinkWriteCallback(write, original!, `${context} has member 'write' that`),\n    type\n  };\n}\n\nfunction convertUnderlyingSinkAbortCallback(\n  fn: UnderlyingSinkAbortCallback,\n  original: UnderlyingSink,\n  context: string\n): (reason: any) => Promise {\n  assertFunction(fn, context);\n  return (reason: any) => promiseCall(fn, original, [reason]);\n}\n\nfunction convertUnderlyingSinkCloseCallback(\n  fn: UnderlyingSinkCloseCallback,\n  original: UnderlyingSink,\n  context: string\n): () => Promise {\n  assertFunction(fn, context);\n  return () => promiseCall(fn, original, []);\n}\n\nfunction convertUnderlyingSinkStartCallback(\n  fn: UnderlyingSinkStartCallback,\n  original: UnderlyingSink,\n  context: string\n): UnderlyingSinkStartCallback {\n  assertFunction(fn, context);\n  return (controller: WritableStreamDefaultController) => reflectCall(fn, original, [controller]);\n}\n\nfunction convertUnderlyingSinkWriteCallback(\n  fn: UnderlyingSinkWriteCallback,\n  original: UnderlyingSink,\n  context: string\n): (chunk: W, controller: WritableStreamDefaultController) => Promise {\n  assertFunction(fn, context);\n  return (chunk: W, controller: WritableStreamDefaultController) => promiseCall(fn, original, [chunk, controller]);\n}\n","import { IsWritableStream, WritableStream } from '../writable-stream';\n\nexport function assertWritableStream(x: unknown, context: string): asserts x is WritableStream {\n  if (!IsWritableStream(x)) {\n    throw new TypeError(`${context} is not a WritableStream.`);\n  }\n}\n","/**\n * A signal object that allows you to communicate with a request and abort it if required\n * via its associated `AbortController` object.\n *\n * @remarks\n *   This interface is compatible with the `AbortSignal` interface defined in TypeScript's DOM types.\n *   It is redefined here, so it can be polyfilled without a DOM, for example with\n *   {@link https://www.npmjs.com/package/abortcontroller-polyfill | abortcontroller-polyfill} in a Node environment.\n *\n * @public\n */\nexport interface AbortSignal {\n  /**\n   * Whether the request is aborted.\n   */\n  readonly aborted: boolean;\n\n  /**\n   * Add an event listener to be triggered when this signal becomes aborted.\n   */\n  addEventListener(type: 'abort', listener: () => void): void;\n\n  /**\n   * Remove an event listener that was previously added with {@link AbortSignal.addEventListener}.\n   */\n  removeEventListener(type: 'abort', listener: () => void): void;\n}\n\nexport function isAbortSignal(value: unknown): value is AbortSignal {\n  if (typeof value !== 'object' || value === null) {\n    return false;\n  }\n  try {\n    return typeof (value as AbortSignal).aborted === 'boolean';\n  } catch {\n    // AbortSignal.prototype.aborted throws if its brand check fails\n    return false;\n  }\n}\n\n/**\n * A controller object that allows you to abort an `AbortSignal` when desired.\n *\n * @remarks\n *   This interface is compatible with the `AbortController` interface defined in TypeScript's DOM types.\n *   It is redefined here, so it can be polyfilled without a DOM, for example with\n *   {@link https://www.npmjs.com/package/abortcontroller-polyfill | abortcontroller-polyfill} in a Node environment.\n *\n * @internal\n */\nexport interface AbortController {\n  readonly signal: AbortSignal;\n\n  abort(): void;\n}\n\ninterface AbortControllerConstructor {\n  new(): AbortController;\n}\n\nconst supportsAbortController = typeof (AbortController as any) === 'function';\n\n/**\n * Construct a new AbortController, if supported by the platform.\n *\n * @internal\n */\nexport function createAbortController(): AbortController | undefined {\n  if (supportsAbortController) {\n    return new (AbortController as AbortControllerConstructor)();\n  }\n  return undefined;\n}\n","import assert from '../stub/assert';\nimport {\n  newPromise,\n  promiseRejectedWith,\n  promiseResolvedWith,\n  setPromiseIsHandledToTrue,\n  uponPromise\n} from './helpers/webidl';\nimport {\n  DequeueValue,\n  EnqueueValueWithSize,\n  PeekQueueValue,\n  QueuePair,\n  ResetQueue\n} from './abstract-ops/queue-with-sizes';\nimport { QueuingStrategy, QueuingStrategySizeCallback } from './queuing-strategy';\nimport { SimpleQueue } from './simple-queue';\nimport { typeIsObject } from './helpers/miscellaneous';\nimport { AbortSteps, ErrorSteps } from './abstract-ops/internal-methods';\nimport { IsNonNegativeNumber } from './abstract-ops/miscellaneous';\nimport { ExtractHighWaterMark, ExtractSizeAlgorithm } from './abstract-ops/queuing-strategy';\nimport { convertQueuingStrategy } from './validators/queuing-strategy';\nimport {\n  UnderlyingSink,\n  UnderlyingSinkAbortCallback,\n  UnderlyingSinkCloseCallback,\n  UnderlyingSinkStartCallback,\n  UnderlyingSinkWriteCallback,\n  ValidatedUnderlyingSink\n} from './writable-stream/underlying-sink';\nimport { assertObject, assertRequiredArgument } from './validators/basic';\nimport { convertUnderlyingSink } from './validators/underlying-sink';\nimport { assertWritableStream } from './validators/writable-stream';\nimport { AbortController, AbortSignal, createAbortController } from './abort-signal';\n\ntype WritableStreamState = 'writable' | 'closed' | 'erroring' | 'errored';\n\ninterface WriteOrCloseRequest {\n  _resolve: (value?: undefined) => void;\n  _reject: (reason: any) => void;\n}\n\ntype WriteRequest = WriteOrCloseRequest;\ntype CloseRequest = WriteOrCloseRequest;\n\ninterface PendingAbortRequest {\n  _promise: Promise;\n  _resolve: (value?: undefined) => void;\n  _reject: (reason: any) => void;\n  _reason: any;\n  _wasAlreadyErroring: boolean;\n}\n\n/**\n * A writable stream represents a destination for data, into which you can write.\n *\n * @public\n */\nclass WritableStream {\n  /** @internal */\n  _state!: WritableStreamState;\n  /** @internal */\n  _storedError: any;\n  /** @internal */\n  _writer: WritableStreamDefaultWriter | undefined;\n  /** @internal */\n  _writableStreamController!: WritableStreamDefaultController;\n  /** @internal */\n  _writeRequests!: SimpleQueue;\n  /** @internal */\n  _inFlightWriteRequest: WriteRequest | undefined;\n  /** @internal */\n  _closeRequest: CloseRequest | undefined;\n  /** @internal */\n  _inFlightCloseRequest: CloseRequest | undefined;\n  /** @internal */\n  _pendingAbortRequest: PendingAbortRequest | undefined;\n  /** @internal */\n  _backpressure!: boolean;\n\n  constructor(underlyingSink?: UnderlyingSink, strategy?: QueuingStrategy);\n  constructor(rawUnderlyingSink: UnderlyingSink | null | undefined = {},\n              rawStrategy: QueuingStrategy | null | undefined = {}) {\n    if (rawUnderlyingSink === undefined) {\n      rawUnderlyingSink = null;\n    } else {\n      assertObject(rawUnderlyingSink, 'First parameter');\n    }\n\n    const strategy = convertQueuingStrategy(rawStrategy, 'Second parameter');\n    const underlyingSink = convertUnderlyingSink(rawUnderlyingSink, 'First parameter');\n\n    InitializeWritableStream(this);\n\n    const type = underlyingSink.type;\n    if (type !== undefined) {\n      throw new RangeError('Invalid type is specified');\n    }\n\n    const sizeAlgorithm = ExtractSizeAlgorithm(strategy);\n    const highWaterMark = ExtractHighWaterMark(strategy, 1);\n\n    SetUpWritableStreamDefaultControllerFromUnderlyingSink(this, underlyingSink, highWaterMark, sizeAlgorithm);\n  }\n\n  /**\n   * Returns whether or not the writable stream is locked to a writer.\n   */\n  get locked(): boolean {\n    if (!IsWritableStream(this)) {\n      throw streamBrandCheckException('locked');\n    }\n\n    return IsWritableStreamLocked(this);\n  }\n\n  /**\n   * Aborts the stream, signaling that the producer can no longer successfully write to the stream and it is to be\n   * immediately moved to an errored state, with any queued-up writes discarded. This will also execute any abort\n   * mechanism of the underlying sink.\n   *\n   * The returned promise will fulfill if the stream shuts down successfully, or reject if the underlying sink signaled\n   * that there was an error doing so. Additionally, it will reject with a `TypeError` (without attempting to cancel\n   * the stream) if the stream is currently locked.\n   */\n  abort(reason: any = undefined): Promise {\n    if (!IsWritableStream(this)) {\n      return promiseRejectedWith(streamBrandCheckException('abort'));\n    }\n\n    if (IsWritableStreamLocked(this)) {\n      return promiseRejectedWith(new TypeError('Cannot abort a stream that already has a writer'));\n    }\n\n    return WritableStreamAbort(this, reason);\n  }\n\n  /**\n   * Closes the stream. The underlying sink will finish processing any previously-written chunks, before invoking its\n   * close behavior. During this time any further attempts to write will fail (without erroring the stream).\n   *\n   * The method returns a promise that will fulfill if all remaining chunks are successfully written and the stream\n   * successfully closes, or rejects if an error is encountered during this process. Additionally, it will reject with\n   * a `TypeError` (without attempting to cancel the stream) if the stream is currently locked.\n   */\n  close() {\n    if (!IsWritableStream(this)) {\n      return promiseRejectedWith(streamBrandCheckException('close'));\n    }\n\n    if (IsWritableStreamLocked(this)) {\n      return promiseRejectedWith(new TypeError('Cannot close a stream that already has a writer'));\n    }\n\n    if (WritableStreamCloseQueuedOrInFlight(this)) {\n      return promiseRejectedWith(new TypeError('Cannot close an already-closing stream'));\n    }\n\n    return WritableStreamClose(this);\n  }\n\n  /**\n   * Creates a {@link WritableStreamDefaultWriter | writer} and locks the stream to the new writer. While the stream\n   * is locked, no other writer can be acquired until this one is released.\n   *\n   * This functionality is especially useful for creating abstractions that desire the ability to write to a stream\n   * without interruption or interleaving. By getting a writer for the stream, you can ensure nobody else can write at\n   * the same time, which would cause the resulting written data to be unpredictable and probably useless.\n   */\n  getWriter(): WritableStreamDefaultWriter {\n    if (!IsWritableStream(this)) {\n      throw streamBrandCheckException('getWriter');\n    }\n\n    return AcquireWritableStreamDefaultWriter(this);\n  }\n}\n\nObject.defineProperties(WritableStream.prototype, {\n  abort: { enumerable: true },\n  close: { enumerable: true },\n  getWriter: { enumerable: true },\n  locked: { enumerable: true }\n});\nif (typeof Symbol.toStringTag === 'symbol') {\n  Object.defineProperty(WritableStream.prototype, Symbol.toStringTag, {\n    value: 'WritableStream',\n    configurable: true\n  });\n}\n\nexport {\n  AcquireWritableStreamDefaultWriter,\n  CreateWritableStream,\n  IsWritableStream,\n  IsWritableStreamLocked,\n  WritableStream,\n  WritableStreamAbort,\n  WritableStreamDefaultControllerErrorIfNeeded,\n  WritableStreamDefaultWriterCloseWithErrorPropagation,\n  WritableStreamDefaultWriterRelease,\n  WritableStreamDefaultWriterWrite,\n  WritableStreamCloseQueuedOrInFlight,\n  UnderlyingSink,\n  UnderlyingSinkStartCallback,\n  UnderlyingSinkWriteCallback,\n  UnderlyingSinkCloseCallback,\n  UnderlyingSinkAbortCallback\n};\n\n// Abstract operations for the WritableStream.\n\nfunction AcquireWritableStreamDefaultWriter(stream: WritableStream): WritableStreamDefaultWriter {\n  return new WritableStreamDefaultWriter(stream);\n}\n\n// Throws if and only if startAlgorithm throws.\nfunction CreateWritableStream(startAlgorithm: () => void | PromiseLike,\n                                 writeAlgorithm: (chunk: W) => Promise,\n                                 closeAlgorithm: () => Promise,\n                                 abortAlgorithm: (reason: any) => Promise,\n                                 highWaterMark = 1,\n                                 sizeAlgorithm: QueuingStrategySizeCallback = () => 1) {\n  assert(IsNonNegativeNumber(highWaterMark));\n\n  const stream: WritableStream = Object.create(WritableStream.prototype);\n  InitializeWritableStream(stream);\n\n  const controller: WritableStreamDefaultController = Object.create(WritableStreamDefaultController.prototype);\n\n  SetUpWritableStreamDefaultController(stream, controller, startAlgorithm, writeAlgorithm, closeAlgorithm,\n                                       abortAlgorithm, highWaterMark, sizeAlgorithm);\n  return stream;\n}\n\nfunction InitializeWritableStream(stream: WritableStream) {\n  stream._state = 'writable';\n\n  // The error that will be reported by new method calls once the state becomes errored. Only set when [[state]] is\n  // 'erroring' or 'errored'. May be set to an undefined value.\n  stream._storedError = undefined;\n\n  stream._writer = undefined;\n\n  // Initialize to undefined first because the constructor of the controller checks this\n  // variable to validate the caller.\n  stream._writableStreamController = undefined!;\n\n  // This queue is placed here instead of the writer class in order to allow for passing a writer to the next data\n  // producer without waiting for the queued writes to finish.\n  stream._writeRequests = new SimpleQueue();\n\n  // Write requests are removed from _writeRequests when write() is called on the underlying sink. This prevents\n  // them from being erroneously rejected on error. If a write() call is in-flight, the request is stored here.\n  stream._inFlightWriteRequest = undefined;\n\n  // The promise that was returned from writer.close(). Stored here because it may be fulfilled after the writer\n  // has been detached.\n  stream._closeRequest = undefined;\n\n  // Close request is removed from _closeRequest when close() is called on the underlying sink. This prevents it\n  // from being erroneously rejected on error. If a close() call is in-flight, the request is stored here.\n  stream._inFlightCloseRequest = undefined;\n\n  // The promise that was returned from writer.abort(). This may also be fulfilled after the writer has detached.\n  stream._pendingAbortRequest = undefined;\n\n  // The backpressure signal set by the controller.\n  stream._backpressure = false;\n}\n\nfunction IsWritableStream(x: unknown): x is WritableStream {\n  if (!typeIsObject(x)) {\n    return false;\n  }\n\n  if (!Object.prototype.hasOwnProperty.call(x, '_writableStreamController')) {\n    return false;\n  }\n\n  return x instanceof WritableStream;\n}\n\nfunction IsWritableStreamLocked(stream: WritableStream): boolean {\n  assert(IsWritableStream(stream));\n\n  if (stream._writer === undefined) {\n    return false;\n  }\n\n  return true;\n}\n\nfunction WritableStreamAbort(stream: WritableStream, reason: any): Promise {\n  if (stream._state === 'closed' || stream._state === 'errored') {\n    return promiseResolvedWith(undefined);\n  }\n  stream._writableStreamController._abortReason = reason;\n  stream._writableStreamController._abortController?.abort();\n\n  // TypeScript narrows the type of `stream._state` down to 'writable' | 'erroring',\n  // but it doesn't know that signaling abort runs author code that might have changed the state.\n  // Widen the type again by casting to WritableStreamState.\n  const state = stream._state as WritableStreamState;\n\n  if (state === 'closed' || state === 'errored') {\n    return promiseResolvedWith(undefined);\n  }\n  if (stream._pendingAbortRequest !== undefined) {\n    return stream._pendingAbortRequest._promise;\n  }\n\n  assert(state === 'writable' || state === 'erroring');\n\n  let wasAlreadyErroring = false;\n  if (state === 'erroring') {\n    wasAlreadyErroring = true;\n    // reason will not be used, so don't keep a reference to it.\n    reason = undefined;\n  }\n\n  const promise = newPromise((resolve, reject) => {\n    stream._pendingAbortRequest = {\n      _promise: undefined!,\n      _resolve: resolve,\n      _reject: reject,\n      _reason: reason,\n      _wasAlreadyErroring: wasAlreadyErroring\n    };\n  });\n  stream._pendingAbortRequest!._promise = promise;\n\n  if (!wasAlreadyErroring) {\n    WritableStreamStartErroring(stream, reason);\n  }\n\n  return promise;\n}\n\nfunction WritableStreamClose(stream: WritableStream): Promise {\n  const state = stream._state;\n  if (state === 'closed' || state === 'errored') {\n    return promiseRejectedWith(new TypeError(\n      `The stream (in ${state} state) is not in the writable state and cannot be closed`));\n  }\n\n  assert(state === 'writable' || state === 'erroring');\n  assert(!WritableStreamCloseQueuedOrInFlight(stream));\n\n  const promise = newPromise((resolve, reject) => {\n    const closeRequest: CloseRequest = {\n      _resolve: resolve,\n      _reject: reject\n    };\n\n    stream._closeRequest = closeRequest;\n  });\n\n  const writer = stream._writer;\n  if (writer !== undefined && stream._backpressure && state === 'writable') {\n    defaultWriterReadyPromiseResolve(writer);\n  }\n\n  WritableStreamDefaultControllerClose(stream._writableStreamController);\n\n  return promise;\n}\n\n// WritableStream API exposed for controllers.\n\nfunction WritableStreamAddWriteRequest(stream: WritableStream): Promise {\n  assert(IsWritableStreamLocked(stream));\n  assert(stream._state === 'writable');\n\n  const promise = newPromise((resolve, reject) => {\n    const writeRequest: WriteRequest = {\n      _resolve: resolve,\n      _reject: reject\n    };\n\n    stream._writeRequests.push(writeRequest);\n  });\n\n  return promise;\n}\n\nfunction WritableStreamDealWithRejection(stream: WritableStream, error: any) {\n  const state = stream._state;\n\n  if (state === 'writable') {\n    WritableStreamStartErroring(stream, error);\n    return;\n  }\n\n  assert(state === 'erroring');\n  WritableStreamFinishErroring(stream);\n}\n\nfunction WritableStreamStartErroring(stream: WritableStream, reason: any) {\n  assert(stream._storedError === undefined);\n  assert(stream._state === 'writable');\n\n  const controller = stream._writableStreamController;\n  assert(controller !== undefined);\n\n  stream._state = 'erroring';\n  stream._storedError = reason;\n  const writer = stream._writer;\n  if (writer !== undefined) {\n    WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, reason);\n  }\n\n  if (!WritableStreamHasOperationMarkedInFlight(stream) && controller._started) {\n    WritableStreamFinishErroring(stream);\n  }\n}\n\nfunction WritableStreamFinishErroring(stream: WritableStream) {\n  assert(stream._state === 'erroring');\n  assert(!WritableStreamHasOperationMarkedInFlight(stream));\n  stream._state = 'errored';\n  stream._writableStreamController[ErrorSteps]();\n\n  const storedError = stream._storedError;\n  stream._writeRequests.forEach(writeRequest => {\n    writeRequest._reject(storedError);\n  });\n  stream._writeRequests = new SimpleQueue();\n\n  if (stream._pendingAbortRequest === undefined) {\n    WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream);\n    return;\n  }\n\n  const abortRequest = stream._pendingAbortRequest;\n  stream._pendingAbortRequest = undefined;\n\n  if (abortRequest._wasAlreadyErroring) {\n    abortRequest._reject(storedError);\n    WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream);\n    return;\n  }\n\n  const promise = stream._writableStreamController[AbortSteps](abortRequest._reason);\n  uponPromise(\n    promise,\n    () => {\n      abortRequest._resolve();\n      WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream);\n    },\n    (reason: any) => {\n      abortRequest._reject(reason);\n      WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream);\n    });\n}\n\nfunction WritableStreamFinishInFlightWrite(stream: WritableStream) {\n  assert(stream._inFlightWriteRequest !== undefined);\n  stream._inFlightWriteRequest!._resolve(undefined);\n  stream._inFlightWriteRequest = undefined;\n}\n\nfunction WritableStreamFinishInFlightWriteWithError(stream: WritableStream, error: any) {\n  assert(stream._inFlightWriteRequest !== undefined);\n  stream._inFlightWriteRequest!._reject(error);\n  stream._inFlightWriteRequest = undefined;\n\n  assert(stream._state === 'writable' || stream._state === 'erroring');\n\n  WritableStreamDealWithRejection(stream, error);\n}\n\nfunction WritableStreamFinishInFlightClose(stream: WritableStream) {\n  assert(stream._inFlightCloseRequest !== undefined);\n  stream._inFlightCloseRequest!._resolve(undefined);\n  stream._inFlightCloseRequest = undefined;\n\n  const state = stream._state;\n\n  assert(state === 'writable' || state === 'erroring');\n\n  if (state === 'erroring') {\n    // The error was too late to do anything, so it is ignored.\n    stream._storedError = undefined;\n    if (stream._pendingAbortRequest !== undefined) {\n      stream._pendingAbortRequest._resolve();\n      stream._pendingAbortRequest = undefined;\n    }\n  }\n\n  stream._state = 'closed';\n\n  const writer = stream._writer;\n  if (writer !== undefined) {\n    defaultWriterClosedPromiseResolve(writer);\n  }\n\n  assert(stream._pendingAbortRequest === undefined);\n  assert(stream._storedError === undefined);\n}\n\nfunction WritableStreamFinishInFlightCloseWithError(stream: WritableStream, error: any) {\n  assert(stream._inFlightCloseRequest !== undefined);\n  stream._inFlightCloseRequest!._reject(error);\n  stream._inFlightCloseRequest = undefined;\n\n  assert(stream._state === 'writable' || stream._state === 'erroring');\n\n  // Never execute sink abort() after sink close().\n  if (stream._pendingAbortRequest !== undefined) {\n    stream._pendingAbortRequest._reject(error);\n    stream._pendingAbortRequest = undefined;\n  }\n  WritableStreamDealWithRejection(stream, error);\n}\n\n// TODO(ricea): Fix alphabetical order.\nfunction WritableStreamCloseQueuedOrInFlight(stream: WritableStream): boolean {\n  if (stream._closeRequest === undefined && stream._inFlightCloseRequest === undefined) {\n    return false;\n  }\n\n  return true;\n}\n\nfunction WritableStreamHasOperationMarkedInFlight(stream: WritableStream): boolean {\n  if (stream._inFlightWriteRequest === undefined && stream._inFlightCloseRequest === undefined) {\n    return false;\n  }\n\n  return true;\n}\n\nfunction WritableStreamMarkCloseRequestInFlight(stream: WritableStream) {\n  assert(stream._inFlightCloseRequest === undefined);\n  assert(stream._closeRequest !== undefined);\n  stream._inFlightCloseRequest = stream._closeRequest;\n  stream._closeRequest = undefined;\n}\n\nfunction WritableStreamMarkFirstWriteRequestInFlight(stream: WritableStream) {\n  assert(stream._inFlightWriteRequest === undefined);\n  assert(stream._writeRequests.length !== 0);\n  stream._inFlightWriteRequest = stream._writeRequests.shift();\n}\n\nfunction WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream: WritableStream) {\n  assert(stream._state === 'errored');\n  if (stream._closeRequest !== undefined) {\n    assert(stream._inFlightCloseRequest === undefined);\n\n    stream._closeRequest._reject(stream._storedError);\n    stream._closeRequest = undefined;\n  }\n  const writer = stream._writer;\n  if (writer !== undefined) {\n    defaultWriterClosedPromiseReject(writer, stream._storedError);\n  }\n}\n\nfunction WritableStreamUpdateBackpressure(stream: WritableStream, backpressure: boolean) {\n  assert(stream._state === 'writable');\n  assert(!WritableStreamCloseQueuedOrInFlight(stream));\n\n  const writer = stream._writer;\n  if (writer !== undefined && backpressure !== stream._backpressure) {\n    if (backpressure) {\n      defaultWriterReadyPromiseReset(writer);\n    } else {\n      assert(!backpressure);\n\n      defaultWriterReadyPromiseResolve(writer);\n    }\n  }\n\n  stream._backpressure = backpressure;\n}\n\n/**\n * A default writer vended by a {@link WritableStream}.\n *\n * @public\n */\nexport class WritableStreamDefaultWriter {\n  /** @internal */\n  _ownerWritableStream: WritableStream;\n  /** @internal */\n  _closedPromise!: Promise;\n  /** @internal */\n  _closedPromise_resolve?: (value?: undefined) => void;\n  /** @internal */\n  _closedPromise_reject?: (reason: any) => void;\n  /** @internal */\n  _closedPromiseState!: 'pending' | 'resolved' | 'rejected';\n  /** @internal */\n  _readyPromise!: Promise;\n  /** @internal */\n  _readyPromise_resolve?: (value?: undefined) => void;\n  /** @internal */\n  _readyPromise_reject?: (reason: any) => void;\n  /** @internal */\n  _readyPromiseState!: 'pending' | 'fulfilled' | 'rejected';\n\n  constructor(stream: WritableStream) {\n    assertRequiredArgument(stream, 1, 'WritableStreamDefaultWriter');\n    assertWritableStream(stream, 'First parameter');\n\n    if (IsWritableStreamLocked(stream)) {\n      throw new TypeError('This stream has already been locked for exclusive writing by another writer');\n    }\n\n    this._ownerWritableStream = stream;\n    stream._writer = this;\n\n    const state = stream._state;\n\n    if (state === 'writable') {\n      if (!WritableStreamCloseQueuedOrInFlight(stream) && stream._backpressure) {\n        defaultWriterReadyPromiseInitialize(this);\n      } else {\n        defaultWriterReadyPromiseInitializeAsResolved(this);\n      }\n\n      defaultWriterClosedPromiseInitialize(this);\n    } else if (state === 'erroring') {\n      defaultWriterReadyPromiseInitializeAsRejected(this, stream._storedError);\n      defaultWriterClosedPromiseInitialize(this);\n    } else if (state === 'closed') {\n      defaultWriterReadyPromiseInitializeAsResolved(this);\n      defaultWriterClosedPromiseInitializeAsResolved(this);\n    } else {\n      assert(state === 'errored');\n\n      const storedError = stream._storedError;\n      defaultWriterReadyPromiseInitializeAsRejected(this, storedError);\n      defaultWriterClosedPromiseInitializeAsRejected(this, storedError);\n    }\n  }\n\n  /**\n   * Returns a promise that will be fulfilled when the stream becomes closed, or rejected if the stream ever errors or\n   * the writer’s lock is released before the stream finishes closing.\n   */\n  get closed(): Promise {\n    if (!IsWritableStreamDefaultWriter(this)) {\n      return promiseRejectedWith(defaultWriterBrandCheckException('closed'));\n    }\n\n    return this._closedPromise;\n  }\n\n  /**\n   * Returns the desired size to fill the stream’s internal queue. It can be negative, if the queue is over-full.\n   * A producer can use this information to determine the right amount of data to write.\n   *\n   * It will be `null` if the stream cannot be successfully written to (due to either being errored, or having an abort\n   * queued up). It will return zero if the stream is closed. And the getter will throw an exception if invoked when\n   * the writer’s lock is released.\n   */\n  get desiredSize(): number | null {\n    if (!IsWritableStreamDefaultWriter(this)) {\n      throw defaultWriterBrandCheckException('desiredSize');\n    }\n\n    if (this._ownerWritableStream === undefined) {\n      throw defaultWriterLockException('desiredSize');\n    }\n\n    return WritableStreamDefaultWriterGetDesiredSize(this);\n  }\n\n  /**\n   * Returns a promise that will be fulfilled when the desired size to fill the stream’s internal queue transitions\n   * from non-positive to positive, signaling that it is no longer applying backpressure. Once the desired size dips\n   * back to zero or below, the getter will return a new promise that stays pending until the next transition.\n   *\n   * If the stream becomes errored or aborted, or the writer’s lock is released, the returned promise will become\n   * rejected.\n   */\n  get ready(): Promise {\n    if (!IsWritableStreamDefaultWriter(this)) {\n      return promiseRejectedWith(defaultWriterBrandCheckException('ready'));\n    }\n\n    return this._readyPromise;\n  }\n\n  /**\n   * If the reader is active, behaves the same as {@link WritableStream.abort | stream.abort(reason)}.\n   */\n  abort(reason: any = undefined): Promise {\n    if (!IsWritableStreamDefaultWriter(this)) {\n      return promiseRejectedWith(defaultWriterBrandCheckException('abort'));\n    }\n\n    if (this._ownerWritableStream === undefined) {\n      return promiseRejectedWith(defaultWriterLockException('abort'));\n    }\n\n    return WritableStreamDefaultWriterAbort(this, reason);\n  }\n\n  /**\n   * If the reader is active, behaves the same as {@link WritableStream.close | stream.close()}.\n   */\n  close(): Promise {\n    if (!IsWritableStreamDefaultWriter(this)) {\n      return promiseRejectedWith(defaultWriterBrandCheckException('close'));\n    }\n\n    const stream = this._ownerWritableStream;\n\n    if (stream === undefined) {\n      return promiseRejectedWith(defaultWriterLockException('close'));\n    }\n\n    if (WritableStreamCloseQueuedOrInFlight(stream)) {\n      return promiseRejectedWith(new TypeError('Cannot close an already-closing stream'));\n    }\n\n    return WritableStreamDefaultWriterClose(this);\n  }\n\n  /**\n   * Releases the writer’s lock on the corresponding stream. After the lock is released, the writer is no longer active.\n   * If the associated stream is errored when the lock is released, the writer will appear errored in the same way from\n   * now on; otherwise, the writer will appear closed.\n   *\n   * Note that the lock can still be released even if some ongoing writes have not yet finished (i.e. even if the\n   * promises returned from previous calls to {@link WritableStreamDefaultWriter.write | write()} have not yet settled).\n   * It’s not necessary to hold the lock on the writer for the duration of the write; the lock instead simply prevents\n   * other producers from writing in an interleaved manner.\n   */\n  releaseLock(): void {\n    if (!IsWritableStreamDefaultWriter(this)) {\n      throw defaultWriterBrandCheckException('releaseLock');\n    }\n\n    const stream = this._ownerWritableStream;\n\n    if (stream === undefined) {\n      return;\n    }\n\n    assert(stream._writer !== undefined);\n\n    WritableStreamDefaultWriterRelease(this);\n  }\n\n  /**\n   * Writes the given chunk to the writable stream, by waiting until any previous writes have finished successfully,\n   * and then sending the chunk to the underlying sink's {@link UnderlyingSink.write | write()} method. It will return\n   * a promise that fulfills with undefined upon a successful write, or rejects if the write fails or stream becomes\n   * errored before the writing process is initiated.\n   *\n   * Note that what \"success\" means is up to the underlying sink; it might indicate simply that the chunk has been\n   * accepted, and not necessarily that it is safely saved to its ultimate destination.\n   */\n  write(chunk: W): Promise;\n  write(chunk: W = undefined!): Promise {\n    if (!IsWritableStreamDefaultWriter(this)) {\n      return promiseRejectedWith(defaultWriterBrandCheckException('write'));\n    }\n\n    if (this._ownerWritableStream === undefined) {\n      return promiseRejectedWith(defaultWriterLockException('write to'));\n    }\n\n    return WritableStreamDefaultWriterWrite(this, chunk);\n  }\n}\n\nObject.defineProperties(WritableStreamDefaultWriter.prototype, {\n  abort: { enumerable: true },\n  close: { enumerable: true },\n  releaseLock: { enumerable: true },\n  write: { enumerable: true },\n  closed: { enumerable: true },\n  desiredSize: { enumerable: true },\n  ready: { enumerable: true }\n});\nif (typeof Symbol.toStringTag === 'symbol') {\n  Object.defineProperty(WritableStreamDefaultWriter.prototype, Symbol.toStringTag, {\n    value: 'WritableStreamDefaultWriter',\n    configurable: true\n  });\n}\n\n// Abstract operations for the WritableStreamDefaultWriter.\n\nfunction IsWritableStreamDefaultWriter(x: any): x is WritableStreamDefaultWriter {\n  if (!typeIsObject(x)) {\n    return false;\n  }\n\n  if (!Object.prototype.hasOwnProperty.call(x, '_ownerWritableStream')) {\n    return false;\n  }\n\n  return x instanceof WritableStreamDefaultWriter;\n}\n\n// A client of WritableStreamDefaultWriter may use these functions directly to bypass state check.\n\nfunction WritableStreamDefaultWriterAbort(writer: WritableStreamDefaultWriter, reason: any) {\n  const stream = writer._ownerWritableStream;\n\n  assert(stream !== undefined);\n\n  return WritableStreamAbort(stream, reason);\n}\n\nfunction WritableStreamDefaultWriterClose(writer: WritableStreamDefaultWriter): Promise {\n  const stream = writer._ownerWritableStream;\n\n  assert(stream !== undefined);\n\n  return WritableStreamClose(stream);\n}\n\nfunction WritableStreamDefaultWriterCloseWithErrorPropagation(writer: WritableStreamDefaultWriter): Promise {\n  const stream = writer._ownerWritableStream;\n\n  assert(stream !== undefined);\n\n  const state = stream._state;\n  if (WritableStreamCloseQueuedOrInFlight(stream) || state === 'closed') {\n    return promiseResolvedWith(undefined);\n  }\n\n  if (state === 'errored') {\n    return promiseRejectedWith(stream._storedError);\n  }\n\n  assert(state === 'writable' || state === 'erroring');\n\n  return WritableStreamDefaultWriterClose(writer);\n}\n\nfunction WritableStreamDefaultWriterEnsureClosedPromiseRejected(writer: WritableStreamDefaultWriter, error: any) {\n  if (writer._closedPromiseState === 'pending') {\n    defaultWriterClosedPromiseReject(writer, error);\n  } else {\n    defaultWriterClosedPromiseResetToRejected(writer, error);\n  }\n}\n\nfunction WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer: WritableStreamDefaultWriter, error: any) {\n  if (writer._readyPromiseState === 'pending') {\n    defaultWriterReadyPromiseReject(writer, error);\n  } else {\n    defaultWriterReadyPromiseResetToRejected(writer, error);\n  }\n}\n\nfunction WritableStreamDefaultWriterGetDesiredSize(writer: WritableStreamDefaultWriter): number | null {\n  const stream = writer._ownerWritableStream;\n  const state = stream._state;\n\n  if (state === 'errored' || state === 'erroring') {\n    return null;\n  }\n\n  if (state === 'closed') {\n    return 0;\n  }\n\n  return WritableStreamDefaultControllerGetDesiredSize(stream._writableStreamController);\n}\n\nfunction WritableStreamDefaultWriterRelease(writer: WritableStreamDefaultWriter) {\n  const stream = writer._ownerWritableStream;\n  assert(stream !== undefined);\n  assert(stream._writer === writer);\n\n  const releasedError = new TypeError(\n    `Writer was released and can no longer be used to monitor the stream's closedness`);\n\n  WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, releasedError);\n\n  // The state transitions to \"errored\" before the sink abort() method runs, but the writer.closed promise is not\n  // rejected until afterwards. This means that simply testing state will not work.\n  WritableStreamDefaultWriterEnsureClosedPromiseRejected(writer, releasedError);\n\n  stream._writer = undefined;\n  writer._ownerWritableStream = undefined!;\n}\n\nfunction WritableStreamDefaultWriterWrite(writer: WritableStreamDefaultWriter, chunk: W): Promise {\n  const stream = writer._ownerWritableStream;\n\n  assert(stream !== undefined);\n\n  const controller = stream._writableStreamController;\n\n  const chunkSize = WritableStreamDefaultControllerGetChunkSize(controller, chunk);\n\n  if (stream !== writer._ownerWritableStream) {\n    return promiseRejectedWith(defaultWriterLockException('write to'));\n  }\n\n  const state = stream._state;\n  if (state === 'errored') {\n    return promiseRejectedWith(stream._storedError);\n  }\n  if (WritableStreamCloseQueuedOrInFlight(stream) || state === 'closed') {\n    return promiseRejectedWith(new TypeError('The stream is closing or closed and cannot be written to'));\n  }\n  if (state === 'erroring') {\n    return promiseRejectedWith(stream._storedError);\n  }\n\n  assert(state === 'writable');\n\n  const promise = WritableStreamAddWriteRequest(stream);\n\n  WritableStreamDefaultControllerWrite(controller, chunk, chunkSize);\n\n  return promise;\n}\n\nconst closeSentinel: unique symbol = {} as any;\n\ntype QueueRecord = W | typeof closeSentinel;\n\n/**\n * Allows control of a {@link WritableStream | writable stream}'s state and internal queue.\n *\n * @public\n */\nexport class WritableStreamDefaultController {\n  /** @internal */\n  _controlledWritableStream!: WritableStream;\n  /** @internal */\n  _queue!: SimpleQueue>>;\n  /** @internal */\n  _queueTotalSize!: number;\n  /** @internal */\n  _abortReason: any;\n  /** @internal */\n  _abortController: AbortController | undefined;\n  /** @internal */\n  _started!: boolean;\n  /** @internal */\n  _strategySizeAlgorithm!: QueuingStrategySizeCallback;\n  /** @internal */\n  _strategyHWM!: number;\n  /** @internal */\n  _writeAlgorithm!: (chunk: W) => Promise;\n  /** @internal */\n  _closeAlgorithm!: () => Promise;\n  /** @internal */\n  _abortAlgorithm!: (reason: any) => Promise;\n\n  private constructor() {\n    throw new TypeError('Illegal constructor');\n  }\n\n  /**\n   * The reason which was passed to `WritableStream.abort(reason)` when the stream was aborted.\n   *\n   * @deprecated\n   *  This property has been removed from the specification, see https://github.com/whatwg/streams/pull/1177.\n   *  Use {@link WritableStreamDefaultController.signal}'s `reason` instead.\n   */\n  get abortReason(): any {\n    if (!IsWritableStreamDefaultController(this)) {\n      throw defaultControllerBrandCheckException('abortReason');\n    }\n    return this._abortReason;\n  }\n\n  /**\n   * An `AbortSignal` that can be used to abort the pending write or close operation when the stream is aborted.\n   */\n  get signal(): AbortSignal {\n    if (!IsWritableStreamDefaultController(this)) {\n      throw defaultControllerBrandCheckException('signal');\n    }\n    if (this._abortController === undefined) {\n      // Older browsers or older Node versions may not support `AbortController` or `AbortSignal`.\n      // We don't want to bundle and ship an `AbortController` polyfill together with our polyfill,\n      // so instead we only implement support for `signal` if we find a global `AbortController` constructor.\n      throw new TypeError('WritableStreamDefaultController.prototype.signal is not supported');\n    }\n    return this._abortController.signal;\n  }\n\n  /**\n   * Closes the controlled writable stream, making all future interactions with it fail with the given error `e`.\n   *\n   * This method is rarely used, since usually it suffices to return a rejected promise from one of the underlying\n   * sink's methods. However, it can be useful for suddenly shutting down a stream in response to an event outside the\n   * normal lifecycle of interactions with the underlying sink.\n   */\n  error(e: any = undefined): void {\n    if (!IsWritableStreamDefaultController(this)) {\n      throw defaultControllerBrandCheckException('error');\n    }\n    const state = this._controlledWritableStream._state;\n    if (state !== 'writable') {\n      // The stream is closed, errored or will be soon. The sink can't do anything useful if it gets an error here, so\n      // just treat it as a no-op.\n      return;\n    }\n\n    WritableStreamDefaultControllerError(this, e);\n  }\n\n  /** @internal */\n  [AbortSteps](reason: any): Promise {\n    const result = this._abortAlgorithm(reason);\n    WritableStreamDefaultControllerClearAlgorithms(this);\n    return result;\n  }\n\n  /** @internal */\n  [ErrorSteps]() {\n    ResetQueue(this);\n  }\n}\n\nObject.defineProperties(WritableStreamDefaultController.prototype, {\n  abortReason: { enumerable: true },\n  signal: { enumerable: true },\n  error: { enumerable: true }\n});\nif (typeof Symbol.toStringTag === 'symbol') {\n  Object.defineProperty(WritableStreamDefaultController.prototype, Symbol.toStringTag, {\n    value: 'WritableStreamDefaultController',\n    configurable: true\n  });\n}\n\n// Abstract operations implementing interface required by the WritableStream.\n\nfunction IsWritableStreamDefaultController(x: any): x is WritableStreamDefaultController {\n  if (!typeIsObject(x)) {\n    return false;\n  }\n\n  if (!Object.prototype.hasOwnProperty.call(x, '_controlledWritableStream')) {\n    return false;\n  }\n\n  return x instanceof WritableStreamDefaultController;\n}\n\nfunction SetUpWritableStreamDefaultController