import { setTimeout as setTimeout$1, clearTimeout as clearTimeout$1, } from 'node:timers' import http from 'node:http' import https from 'node:https' import zlib from 'node:zlib' import Stream, { PassThrough, pipeline as pipeline$1 } from 'node:stream' import { promisify, deprecate, types } from 'node:util' import { format as format$1 } from 'node:url' import { isIP } from 'node:net' import { performance } from 'node:perf_hooks' /** Returns the function bound to the given object. */ const __function_bind = Function.bind.bind(Function.call) /** Returns the function called with the specified values. */ Function.call.bind(Function.call) /** Returns whether an object has a property with the specified name. */ const __object_hasOwnProperty = Function.call.bind( Object.prototype.hasOwnProperty ) /** Returns a string representation of an object. */ Function.call.bind(Object.prototype.toString) /** Returns whether the object prototype exists in another object. */ const __object_isPrototypeOf = Function.call.bind( Object.prototype.isPrototypeOf ) /** Current high resolution millisecond timestamp. */ const __performance_now = performance.now /** Returns the string escaped for use inside regular expressions. */ const __string_escapeRegExp = (value) => value.replace(/[\\^$*+?.()|[\]{}]/g, '\\$&') // @ts-ignore const INTERNALS$3 = new WeakMap() const internalsOf = (target, className, propName) => { const internals = INTERNALS$3.get(target) if (!internals) throw new TypeError( `${className}.${propName} can only be used on instances of ${className}` ) return internals } const allowStringTag = (value) => (value.prototype[Symbol.toStringTag] = value.name) /** Returns any kind of path as a posix path. */ const pathToPosix = (pathname) => String(pathname == null ? '' : pathname) .replace( // convert slashes /\\+/g, '/' ) .replace( // prefix a slash to drive letters /^(?=[A-Za-z]:\/)/, '/' ) .replace( // encode path characters /%/g, '%25' ) .replace(/\n/g, '%0A') .replace(/\r/g, '%0D') .replace(/\t/g, '%09') class DOMException extends Error { constructor(message = '', name = 'Error') { super(message) this.code = 0 this.name = name } } DOMException.INDEX_SIZE_ERR = 1 DOMException.DOMSTRING_SIZE_ERR = 2 DOMException.HIERARCHY_REQUEST_ERR = 3 DOMException.WRONG_DOCUMENT_ERR = 4 DOMException.INVALID_CHARACTER_ERR = 5 DOMException.NO_DATA_ALLOWED_ERR = 6 DOMException.NO_MODIFICATION_ALLOWED_ERR = 7 DOMException.NOT_FOUND_ERR = 8 DOMException.NOT_SUPPORTED_ERR = 9 DOMException.INUSE_ATTRIBUTE_ERR = 10 DOMException.INVALID_STATE_ERR = 11 DOMException.SYNTAX_ERR = 12 DOMException.INVALID_MODIFICATION_ERR = 13 DOMException.NAMESPACE_ERR = 14 DOMException.INVALID_ACCESS_ERR = 15 DOMException.VALIDATION_ERR = 16 DOMException.TYPE_MISMATCH_ERR = 17 DOMException.SECURITY_ERR = 18 DOMException.NETWORK_ERR = 19 DOMException.ABORT_ERR = 20 DOMException.URL_MISMATCH_ERR = 21 DOMException.QUOTA_EXCEEDED_ERR = 22 DOMException.TIMEOUT_ERR = 23 DOMException.INVALID_NODE_TYPE_ERR = 24 DOMException.DATA_CLONE_ERR = 25 allowStringTag(DOMException) /** * Assert a condition. * @param condition The condition that it should satisfy. * @param message The error message. * @param args The arguments for replacing placeholders in the message. */ function assertType(condition, message, ...args) { if (!condition) { throw new TypeError(format(message, args)) } } /** * Convert a text and arguments to one string. * @param message The formating text * @param args The arguments. */ function format(message, args) { let i = 0 return message.replace(/%[os]/gu, () => anyToString(args[i++])) } /** * Convert a value to a string representation. * @param x The value to get the string representation. */ function anyToString(x) { if (typeof x !== 'object' || x === null) { return String(x) } return Object.prototype.toString.call(x) } let currentErrorHandler /** * Print a error message. * @param maybeError The error object. */ function reportError(maybeError) { try { const error = maybeError instanceof Error ? maybeError : new Error(anyToString(maybeError)) // Call the user-defined error handler if exists. if (currentErrorHandler); // Dispatch an `error` event if this is on a browser. if ( typeof dispatchEvent === 'function' && typeof ErrorEvent === 'function' ) { dispatchEvent(new ErrorEvent('error', { error, message: error.message })) } // Emit an `uncaughtException` event if this is on Node.js. //istanbul ignore else else if ( typeof process !== 'undefined' && typeof process.emit === 'function' ) { process.emit('uncaughtException', error) return } // Otherwise, print the error. console.error(error) } catch (_a) { // ignore. } } let currentWarnHandler /** * The warning information. */ class Warning { constructor(code, message) { this.code = code this.message = message } /** * Report this warning. * @param args The arguments of the warning. */ warn(...args) { var _a try { // Call the user-defined warning handler if exists. if (currentWarnHandler); // Otherwise, print the warning. const stack = ( (_a = new Error().stack) !== null && _a !== void 0 ? _a : '' ).replace(/^(?:.+?\n){2}/gu, '\n') console.warn(this.message, ...args, stack) } catch (_b) { // Ignore. } } } const InitEventWasCalledWhileDispatching = new Warning( 'W01', 'Unable to initialize event under dispatching.' ) const FalsyWasAssignedToCancelBubble = new Warning( 'W02', "Assigning any falsy value to 'cancelBubble' property has no effect." ) const TruthyWasAssignedToReturnValue = new Warning( 'W03', "Assigning any truthy value to 'returnValue' property has no effect." ) const NonCancelableEventWasCanceled = new Warning( 'W04', 'Unable to preventDefault on non-cancelable events.' ) const CanceledInPassiveListener = new Warning( 'W05', 'Unable to preventDefault inside passive event listener invocation.' ) const EventListenerWasDuplicated = new Warning( 'W06', "An event listener wasn't added because it has been added already: %o, %o" ) const OptionWasIgnored = new Warning( 'W07', "The %o option value was abandoned because the event listener wasn't added as duplicated." ) const InvalidEventListener = new Warning( 'W08', "The 'callback' argument must be a function or an object that has 'handleEvent' method: %o" ) const InvalidAttributeHandler = new Warning( 'W09', 'Event attribute handler must be a function: %o' ) /*eslint-disable class-methods-use-this */ /** * An implementation of `Event` interface, that wraps a given event object. * `EventTarget` shim can control the internal state of this `Event` objects. * @see https://dom.spec.whatwg.org/#event */ class Event { /** * @see https://dom.spec.whatwg.org/#dom-event-none */ static get NONE() { return NONE } /** * @see https://dom.spec.whatwg.org/#dom-event-capturing_phase */ static get CAPTURING_PHASE() { return CAPTURING_PHASE } /** * @see https://dom.spec.whatwg.org/#dom-event-at_target */ static get AT_TARGET() { return AT_TARGET } /** * @see https://dom.spec.whatwg.org/#dom-event-bubbling_phase */ static get BUBBLING_PHASE() { return BUBBLING_PHASE } /** * Initialize this event instance. * @param type The type of this event. * @param eventInitDict Options to initialize. * @see https://dom.spec.whatwg.org/#dom-event-event */ constructor(type, eventInitDict) { Object.defineProperty(this, 'isTrusted', { value: false, enumerable: true, }) const opts = eventInitDict !== null && eventInitDict !== void 0 ? eventInitDict : {} internalDataMap.set(this, { type: String(type), bubbles: Boolean(opts.bubbles), cancelable: Boolean(opts.cancelable), composed: Boolean(opts.composed), target: null, currentTarget: null, stopPropagationFlag: false, stopImmediatePropagationFlag: false, canceledFlag: false, inPassiveListenerFlag: false, dispatchFlag: false, timeStamp: Date.now(), }) } /** * The type of this event. * @see https://dom.spec.whatwg.org/#dom-event-type */ get type() { return $(this).type } /** * The event target of the current dispatching. * @see https://dom.spec.whatwg.org/#dom-event-target */ get target() { return $(this).target } /** * The event target of the current dispatching. * @deprecated Use the `target` property instead. * @see https://dom.spec.whatwg.org/#dom-event-srcelement */ get srcElement() { return $(this).target } /** * The event target of the current dispatching. * @see https://dom.spec.whatwg.org/#dom-event-currenttarget */ get currentTarget() { return $(this).currentTarget } /** * The event target of the current dispatching. * This doesn't support node tree. * @see https://dom.spec.whatwg.org/#dom-event-composedpath */ composedPath() { const currentTarget = $(this).currentTarget if (currentTarget) { return [currentTarget] } return [] } /** * @see https://dom.spec.whatwg.org/#dom-event-none */ get NONE() { return NONE } /** * @see https://dom.spec.whatwg.org/#dom-event-capturing_phase */ get CAPTURING_PHASE() { return CAPTURING_PHASE } /** * @see https://dom.spec.whatwg.org/#dom-event-at_target */ get AT_TARGET() { return AT_TARGET } /** * @see https://dom.spec.whatwg.org/#dom-event-bubbling_phase */ get BUBBLING_PHASE() { return BUBBLING_PHASE } /** * The current event phase. * @see https://dom.spec.whatwg.org/#dom-event-eventphase */ get eventPhase() { return $(this).dispatchFlag ? 2 : 0 } /** * Stop event bubbling. * Because this shim doesn't support node tree, this merely changes the `cancelBubble` property value. * @see https://dom.spec.whatwg.org/#dom-event-stoppropagation */ stopPropagation() { $(this).stopPropagationFlag = true } /** * `true` if event bubbling was stopped. * @deprecated * @see https://dom.spec.whatwg.org/#dom-event-cancelbubble */ get cancelBubble() { return $(this).stopPropagationFlag } /** * Stop event bubbling if `true` is set. * @deprecated Use the `stopPropagation()` method instead. * @see https://dom.spec.whatwg.org/#dom-event-cancelbubble */ set cancelBubble(value) { if (value) { $(this).stopPropagationFlag = true } else { FalsyWasAssignedToCancelBubble.warn() } } /** * Stop event bubbling and subsequent event listener callings. * @see https://dom.spec.whatwg.org/#dom-event-stopimmediatepropagation */ stopImmediatePropagation() { const data = $(this) data.stopPropagationFlag = data.stopImmediatePropagationFlag = true } /** * `true` if this event will bubble. * @see https://dom.spec.whatwg.org/#dom-event-bubbles */ get bubbles() { return $(this).bubbles } /** * `true` if this event can be canceled by the `preventDefault()` method. * @see https://dom.spec.whatwg.org/#dom-event-cancelable */ get cancelable() { return $(this).cancelable } /** * `true` if the default behavior will act. * @deprecated Use the `defaultPrevented` proeprty instead. * @see https://dom.spec.whatwg.org/#dom-event-returnvalue */ get returnValue() { return !$(this).canceledFlag } /** * Cancel the default behavior if `false` is set. * @deprecated Use the `preventDefault()` method instead. * @see https://dom.spec.whatwg.org/#dom-event-returnvalue */ set returnValue(value) { if (!value) { setCancelFlag($(this)) } else { TruthyWasAssignedToReturnValue.warn() } } /** * Cancel the default behavior. * @see https://dom.spec.whatwg.org/#dom-event-preventdefault */ preventDefault() { setCancelFlag($(this)) } /** * `true` if the default behavior was canceled. * @see https://dom.spec.whatwg.org/#dom-event-defaultprevented */ get defaultPrevented() { return $(this).canceledFlag } /** * @see https://dom.spec.whatwg.org/#dom-event-composed */ get composed() { return $(this).composed } /** * @see https://dom.spec.whatwg.org/#dom-event-istrusted */ //istanbul ignore next get isTrusted() { return false } /** * @see https://dom.spec.whatwg.org/#dom-event-timestamp */ get timeStamp() { return $(this).timeStamp } /** * @deprecated Don't use this method. The constructor did initialization. */ initEvent(type, bubbles = false, cancelable = false) { const data = $(this) if (data.dispatchFlag) { InitEventWasCalledWhileDispatching.warn() return } internalDataMap.set(this, { ...data, type: String(type), bubbles: Boolean(bubbles), cancelable: Boolean(cancelable), target: null, currentTarget: null, stopPropagationFlag: false, stopImmediatePropagationFlag: false, canceledFlag: false, }) } } //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ const NONE = 0 const CAPTURING_PHASE = 1 const AT_TARGET = 2 const BUBBLING_PHASE = 3 /** * Private data for event wrappers. */ const internalDataMap = new WeakMap() /** * Get private data. * @param event The event object to get private data. * @param name The variable name to report. * @returns The private data of the event. */ function $(event, name = 'this') { const retv = internalDataMap.get(event) assertType( retv != null, "'%s' must be an object that Event constructor created, but got another one: %o", name, event ) return retv } /** * https://dom.spec.whatwg.org/#set-the-canceled-flag * @param data private data. */ function setCancelFlag(data) { if (data.inPassiveListenerFlag) { CanceledInPassiveListener.warn() return } if (!data.cancelable) { NonCancelableEventWasCanceled.warn() return } data.canceledFlag = true } // Set enumerable Object.defineProperty(Event, 'NONE', { enumerable: true }) Object.defineProperty(Event, 'CAPTURING_PHASE', { enumerable: true }) Object.defineProperty(Event, 'AT_TARGET', { enumerable: true }) Object.defineProperty(Event, 'BUBBLING_PHASE', { enumerable: true }) const keys$1 = Object.getOwnPropertyNames(Event.prototype) for (let i = 0; i < keys$1.length; ++i) { if (keys$1[i] === 'constructor') { continue } Object.defineProperty(Event.prototype, keys$1[i], { enumerable: true }) } /** * An implementation of `Event` interface, that wraps a given event object. * This class controls the internal state of `Event`. * @see https://dom.spec.whatwg.org/#interface-event */ class EventWrapper extends Event { /** * Wrap a given event object to control states. * @param event The event-like object to wrap. */ static wrap(event) { return new (getWrapperClassOf(event))(event) } constructor(event) { super(event.type, { bubbles: event.bubbles, cancelable: event.cancelable, composed: event.composed, }) if (event.cancelBubble) { super.stopPropagation() } if (event.defaultPrevented) { super.preventDefault() } internalDataMap$1.set(this, { original: event }) // Define accessors const keys = Object.keys(event) for (let i = 0; i < keys.length; ++i) { const key = keys[i] if (!(key in this)) { Object.defineProperty(this, key, defineRedirectDescriptor(event, key)) } } } stopPropagation() { super.stopPropagation() const { original } = $$1(this) if ('stopPropagation' in original) { original.stopPropagation() } } get cancelBubble() { return super.cancelBubble } set cancelBubble(value) { super.cancelBubble = value const { original } = $$1(this) if ('cancelBubble' in original) { original.cancelBubble = value } } stopImmediatePropagation() { super.stopImmediatePropagation() const { original } = $$1(this) if ('stopImmediatePropagation' in original) { original.stopImmediatePropagation() } } get returnValue() { return super.returnValue } set returnValue(value) { super.returnValue = value const { original } = $$1(this) if ('returnValue' in original) { original.returnValue = value } } preventDefault() { super.preventDefault() const { original } = $$1(this) if ('preventDefault' in original) { original.preventDefault() } } get timeStamp() { const { original } = $$1(this) if ('timeStamp' in original) { return original.timeStamp } return super.timeStamp } } /** * Private data for event wrappers. */ const internalDataMap$1 = new WeakMap() /** * Get private data. * @param event The event object to get private data. * @returns The private data of the event. */ function $$1(event) { const retv = internalDataMap$1.get(event) assertType(retv != null, "'this' is expected an Event object, but got", event) return retv } /** * Cache for wrapper classes. * @type {WeakMap} * @private */ const wrapperClassCache = new WeakMap() // Make association for wrappers. wrapperClassCache.set(Object.prototype, EventWrapper) /** * Get the wrapper class of a given prototype. * @param originalEvent The event object to wrap. */ function getWrapperClassOf(originalEvent) { const prototype = Object.getPrototypeOf(originalEvent) if (prototype == null) { return EventWrapper } let wrapper = wrapperClassCache.get(prototype) if (wrapper == null) { wrapper = defineWrapper(getWrapperClassOf(prototype), prototype) wrapperClassCache.set(prototype, wrapper) } return wrapper } /** * Define new wrapper class. * @param BaseEventWrapper The base wrapper class. * @param originalPrototype The prototype of the original event. */ function defineWrapper(BaseEventWrapper, originalPrototype) { class CustomEventWrapper extends BaseEventWrapper {} const keys = Object.keys(originalPrototype) for (let i = 0; i < keys.length; ++i) { Object.defineProperty( CustomEventWrapper.prototype, keys[i], defineRedirectDescriptor(originalPrototype, keys[i]) ) } return CustomEventWrapper } /** * Get the property descriptor to redirect a given property. */ function defineRedirectDescriptor(obj, key) { const d = Object.getOwnPropertyDescriptor(obj, key) return { get() { const original = $$1(this).original const value = original[key] if (typeof value === 'function') { return value.bind(original) } return value }, set(value) { const original = $$1(this).original original[key] = value }, configurable: d.configurable, enumerable: d.enumerable, } } /** * Create a new listener. * @param callback The callback function. * @param capture The capture flag. * @param passive The passive flag. * @param once The once flag. * @param signal The abort signal. * @param signalListener The abort event listener for the abort signal. */ function createListener( callback, capture, passive, once, signal, signalListener ) { return { callback, flags: (capture ? 1 /* Capture */ : 0) | (passive ? 2 /* Passive */ : 0) | (once ? 4 /* Once */ : 0), signal, signalListener, } } /** * Set the `removed` flag to the given listener. * @param listener The listener to check. */ function setRemoved(listener) { listener.flags |= 8 /* Removed */ } /** * Check if the given listener has the `capture` flag or not. * @param listener The listener to check. */ function isCapture(listener) { return (listener.flags & 1) /* Capture */ === 1 /* Capture */ } /** * Check if the given listener has the `passive` flag or not. * @param listener The listener to check. */ function isPassive(listener) { return (listener.flags & 2) /* Passive */ === 2 /* Passive */ } /** * Check if the given listener has the `once` flag or not. * @param listener The listener to check. */ function isOnce(listener) { return (listener.flags & 4) /* Once */ === 4 /* Once */ } /** * Check if the given listener has the `removed` flag or not. * @param listener The listener to check. */ function isRemoved(listener) { return (listener.flags & 8) /* Removed */ === 8 /* Removed */ } /** * Call an event listener. * @param listener The listener to call. * @param target The event target object for `thisArg`. * @param event The event object for the first argument. * @param attribute `true` if this callback is an event attribute handler. */ function invokeCallback({ callback }, target, event) { try { if (typeof callback === 'function') { callback.call(target, event) } else if (typeof callback.handleEvent === 'function') { callback.handleEvent(event) } } catch (thrownError) { reportError(thrownError) } } /** * Find the index of given listener. * This returns `-1` if not found. * @param list The listener list. * @param callback The callback function to find. * @param capture The capture flag to find. */ function findIndexOfListener({ listeners }, callback, capture) { for (let i = 0; i < listeners.length; ++i) { if ( listeners[i].callback === callback && isCapture(listeners[i]) === capture ) { return i } } return -1 } /** * Add the given listener. * Does copy-on-write if needed. * @param list The listener list. * @param callback The callback function. * @param capture The capture flag. * @param passive The passive flag. * @param once The once flag. * @param signal The abort signal. */ function addListener(list, callback, capture, passive, once, signal) { let signalListener if (signal) { signalListener = removeListener.bind(null, list, callback, capture) signal.addEventListener('abort', signalListener) } const listener = createListener( callback, capture, passive, once, signal, signalListener ) if (list.cow) { list.cow = false list.listeners = [...list.listeners, listener] } else { list.listeners.push(listener) } return listener } /** * Remove a listener. * @param list The listener list. * @param callback The callback function to find. * @param capture The capture flag to find. * @returns `true` if it mutated the list directly. */ function removeListener(list, callback, capture) { const index = findIndexOfListener(list, callback, capture) if (index !== -1) { return removeListenerAt(list, index) } return false } /** * Remove a listener. * @param list The listener list. * @param index The index of the target listener. * @param disableCow Disable copy-on-write if true. * @returns `true` if it mutated the `listeners` array directly. */ function removeListenerAt(list, index, disableCow = false) { const listener = list.listeners[index] // Set the removed flag. setRemoved(listener) // Dispose the abort signal listener if exists. if (listener.signal) { listener.signal.removeEventListener('abort', listener.signalListener) } // Remove it from the array. if (list.cow && !disableCow) { list.cow = false list.listeners = list.listeners.filter((_, i) => i !== index) return false } list.listeners.splice(index, 1) return true } /** * Create a new `ListenerListMap` object. */ function createListenerListMap() { return Object.create(null) } /** * Get the listener list of the given type. * If the listener list has not been initialized, initialize and return it. * @param listenerMap The listener list map. * @param type The event type to get. */ function ensureListenerList(listenerMap, type) { var _a return (_a = listenerMap[type]) !== null && _a !== void 0 ? _a : (listenerMap[type] = { attrCallback: undefined, attrListener: undefined, cow: false, listeners: [], }) } /** * An implementation of the `EventTarget` interface. * @see https://dom.spec.whatwg.org/#eventtarget */ class EventTarget { /** * Initialize this instance. */ constructor() { internalDataMap$2.set(this, createListenerListMap()) } // Implementation addEventListener(type0, callback0, options0) { const listenerMap = $$2(this) const { callback, capture, once, passive, signal, type } = normalizeAddOptions(type0, callback0, options0) if ( callback == null || (signal === null || signal === void 0 ? void 0 : signal.aborted) ) { return } const list = ensureListenerList(listenerMap, type) // Find existing listener. const i = findIndexOfListener(list, callback, capture) if (i !== -1) { warnDuplicate(list.listeners[i], passive, once, signal) return } // Add the new listener. addListener(list, callback, capture, passive, once, signal) } // Implementation removeEventListener(type0, callback0, options0) { const listenerMap = $$2(this) const { callback, capture, type } = normalizeOptions( type0, callback0, options0 ) const list = listenerMap[type] if (callback != null && list) { removeListener(list, callback, capture) } } // Implementation dispatchEvent(e) { const list = $$2(this)[String(e.type)] if (list == null) { return true } const event = e instanceof Event ? e : EventWrapper.wrap(e) const eventData = $(event, 'event') if (eventData.dispatchFlag) { throw new DOMException('This event has been in dispatching.') } eventData.dispatchFlag = true eventData.target = eventData.currentTarget = this if (!eventData.stopPropagationFlag) { const { cow, listeners } = list // Set copy-on-write flag. list.cow = true // Call listeners. for (let i = 0; i < listeners.length; ++i) { const listener = listeners[i] // Skip if removed. if (isRemoved(listener)) { continue } // Remove this listener if has the `once` flag. if (isOnce(listener) && removeListenerAt(list, i, !cow)) { // Because this listener was removed, the next index is the // same as the current value. i -= 1 } // Call this listener with the `passive` flag. eventData.inPassiveListenerFlag = isPassive(listener) invokeCallback(listener, this, event) eventData.inPassiveListenerFlag = false // Stop if the `event.stopImmediatePropagation()` method was called. if (eventData.stopImmediatePropagationFlag) { break } } // Restore copy-on-write flag. if (!cow) { list.cow = false } } eventData.target = null eventData.currentTarget = null eventData.stopImmediatePropagationFlag = false eventData.stopPropagationFlag = false eventData.dispatchFlag = false return !eventData.canceledFlag } } /** * Internal data. */ const internalDataMap$2 = new WeakMap() /** * Get private data. * @param target The event target object to get private data. * @param name The variable name to report. * @returns The private data of the event. */ function $$2(target, name = 'this') { const retv = internalDataMap$2.get(target) assertType( retv != null, "'%s' must be an object that EventTarget constructor created, but got another one: %o", name, target ) return retv } /** * Normalize options. * @param options The options to normalize. */ function normalizeAddOptions(type, callback, options) { var _a assertCallback(callback) if (typeof options === 'object' && options !== null) { return { type: String(type), callback: callback !== null && callback !== void 0 ? callback : undefined, capture: Boolean(options.capture), passive: Boolean(options.passive), once: Boolean(options.once), signal: (_a = options.signal) !== null && _a !== void 0 ? _a : undefined, } } return { type: String(type), callback: callback !== null && callback !== void 0 ? callback : undefined, capture: Boolean(options), passive: false, once: false, signal: undefined, } } /** * Normalize options. * @param options The options to normalize. */ function normalizeOptions(type, callback, options) { assertCallback(callback) if (typeof options === 'object' && options !== null) { return { type: String(type), callback: callback !== null && callback !== void 0 ? callback : undefined, capture: Boolean(options.capture), } } return { type: String(type), callback: callback !== null && callback !== void 0 ? callback : undefined, capture: Boolean(options), } } /** * Assert the type of 'callback' argument. * @param callback The callback to check. */ function assertCallback(callback) { if ( typeof callback === 'function' || (typeof callback === 'object' && callback !== null && typeof callback.handleEvent === 'function') ) { return } if (callback == null || typeof callback === 'object') { InvalidEventListener.warn(callback) return } throw new TypeError(format(InvalidEventListener.message, [callback])) } /** * Print warning for duplicated. * @param listener The current listener that is duplicated. * @param passive The passive flag of the new duplicated listener. * @param once The once flag of the new duplicated listener. * @param signal The signal object of the new duplicated listener. */ function warnDuplicate(listener, passive, once, signal) { EventListenerWasDuplicated.warn( isCapture(listener) ? 'capture' : 'bubble', listener.callback ) if (isPassive(listener) !== passive) { OptionWasIgnored.warn('passive') } if (isOnce(listener) !== once) { OptionWasIgnored.warn('once') } if (listener.signal !== signal) { OptionWasIgnored.warn('signal') } } // Set enumerable const keys$1$1 = Object.getOwnPropertyNames(EventTarget.prototype) for (let i = 0; i < keys$1$1.length; ++i) { if (keys$1$1[i] === 'constructor') { continue } Object.defineProperty(EventTarget.prototype, keys$1$1[i], { enumerable: true, }) } // Ensure `eventTarget instanceof window.EventTarget` is `true`. /** * Get the current value of a given event attribute. * @param target The `EventTarget` object to get. * @param type The event type. */ function getEventAttributeValue(target, type) { var _a, _b const listMap = $$2(target, 'target') return (_b = (_a = listMap[type]) === null || _a === void 0 ? void 0 : _a.attrCallback) !== null && _b !== void 0 ? _b : null } /** * Set an event listener to a given event attribute. * @param target The `EventTarget` object to set. * @param type The event type. * @param callback The event listener. */ function setEventAttributeValue(target, type, callback) { if (callback != null && typeof callback !== 'function') { InvalidAttributeHandler.warn(callback) } if ( typeof callback === 'function' || (typeof callback === 'object' && callback !== null) ) { upsertEventAttributeListener(target, type, callback) } else { removeEventAttributeListener(target, type) } } //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Update or insert the given event attribute handler. * @param target The `EventTarget` object to set. * @param type The event type. * @param callback The event listener. */ function upsertEventAttributeListener(target, type, callback) { const list = ensureListenerList($$2(target, 'target'), String(type)) list.attrCallback = callback if (list.attrListener == null) { list.attrListener = addListener( list, defineEventAttributeCallback(list), false, false, false, undefined ) } } /** * Remove the given event attribute handler. * @param target The `EventTarget` object to remove. * @param type The event type. * @param callback The event listener. */ function removeEventAttributeListener(target, type) { const listMap = $$2(target, 'target') const list = listMap[String(type)] if (list && list.attrListener) { removeListener(list, list.attrListener.callback, false) list.attrCallback = list.attrListener = undefined } } /** * Define the callback function for the given listener list object. * It calls `attrCallback` property if the property value is a function. * @param list The `ListenerList` object. */ function defineEventAttributeCallback(list) { return function (event) { const callback = list.attrCallback if (typeof callback === 'function') { callback.call(this, event) } } } /** * Define an event attribute. * @param target The `EventTarget` object to define an event attribute. * @param type The event type to define. * @param _eventClass Unused, but to infer `Event` class type. * @deprecated Use `getEventAttributeValue`/`setEventAttributeValue` pair on your derived class instead because of static analysis friendly. */ function defineEventAttribute(target, type, _eventClass) { Object.defineProperty(target, `on${type}`, { get() { return getEventAttributeValue(this, type) }, set(value) { setEventAttributeValue(this, type, value) }, configurable: true, enumerable: true, }) } /** * @author Toru Nagashima * See LICENSE file in root directory for full license. */ /** * The signal class. * @see https://dom.spec.whatwg.org/#abortsignal */ class AbortSignal extends EventTarget { /** * AbortSignal cannot be constructed directly. */ constructor() { super() throw new TypeError('AbortSignal cannot be constructed directly') } /** * Returns `true` if this `AbortSignal`'s `AbortController` has signaled to abort, and `false` otherwise. */ get aborted() { const aborted = abortedFlags.get(this) if (typeof aborted !== 'boolean') { throw new TypeError( `Expected 'this' to be an 'AbortSignal' object, but got ${ this === null ? 'null' : typeof this }` ) } return aborted } } defineEventAttribute(AbortSignal.prototype, 'abort') /** * Create an AbortSignal object. */ function createAbortSignal() { const signal = Object.create(AbortSignal.prototype) EventTarget.call(signal) abortedFlags.set(signal, false) return signal } /** * Abort a given signal. */ function abortSignal(signal) { if (abortedFlags.get(signal) !== false) { return } abortedFlags.set(signal, true) signal.dispatchEvent({ type: 'abort' }) } /** * Aborted flag for each instances. */ const abortedFlags = new WeakMap() // Properties should be enumerable. Object.defineProperties(AbortSignal.prototype, { aborted: { enumerable: true }, }) // `toString()` should return `"[object AbortSignal]"` if (typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol') { Object.defineProperty(AbortSignal.prototype, Symbol.toStringTag, { configurable: true, value: 'AbortSignal', }) } /** * The AbortController. * @see https://dom.spec.whatwg.org/#abortcontroller */ class AbortController { /** * Initialize this controller. */ constructor() { signals.set(this, createAbortSignal()) } /** * Returns the `AbortSignal` object associated with this object. */ get signal() { return getSignal(this) } /** * Abort and signal to any observers that the associated activity is to be aborted. */ abort() { abortSignal(getSignal(this)) } } /** * Associated signals. */ const signals = new WeakMap() /** * Get the associated signal of a given controller. */ function getSignal(controller) { const signal = signals.get(controller) if (signal == null) { throw new TypeError( `Expected 'this' to be an 'AbortController' object, but got ${ controller === null ? 'null' : typeof controller }` ) } return signal } // Properties should be enumerable. Object.defineProperties(AbortController.prototype, { signal: { enumerable: true }, abort: { enumerable: true }, }) if (typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol') { Object.defineProperty(AbortController.prototype, Symbol.toStringTag, { configurable: true, value: 'AbortController', }) } const INTERNAL$2 = { tick: 0, pool: new Map() } function requestAnimationFrame(callback) { if (!INTERNAL$2.pool.size) { setTimeout$1(() => { const next = __performance_now() for (const func of INTERNAL$2.pool.values()) { func(next) } INTERNAL$2.pool.clear() }, 1000 / 16) } const func = __function_bind(callback, undefined) const tick = ++INTERNAL$2.tick INTERNAL$2.pool.set(tick, func) return tick } function cancelAnimationFrame(requestId) { const timeout = INTERNAL$2.pool.get(requestId) if (timeout) { clearTimeout$1(timeout) INTERNAL$2.pool.delete(requestId) } } function atob(data) { return Buffer.from(data, 'base64').toString('binary') } function btoa(data) { return Buffer.from(data, 'binary').toString('base64') } class Node extends EventTarget { append(...nodesOrDOMStrings) {} appendChild(childNode) { return childNode } after(...nodesOrDOMStrings) {} before(...nodesOrDOMStrings) {} prepend(...nodesOrDOMStrings) {} replaceChild(newChild, oldChild) { return oldChild } removeChild(childNode) { return childNode } get attributes() { return {} } get childNodes() { return [] } get children() { return [] } get ownerDocument() { return null } get nodeValue() { return '' } set nodeValue(value) {} get textContent() { return '' } set textContent(value) {} get previousElementSibling() { return null } get nextElementSibling() { return null } [Symbol.for('nodejs.util.inspect.custom')](depth, options) { return `${this.constructor.name}` } } class DocumentFragment extends Node {} class ShadowRoot extends DocumentFragment { get innerHTML() { return '' } set innerHTML(value) {} } const NodeFilter$1 = Object.assign( { NodeFilter() { throw new TypeError('Illegal constructor') }, }.NodeFilter, { FILTER_ACCEPT: 1, FILTER_REJECT: 2, FILTER_SKIP: 3, SHOW_ALL: 4294967295, SHOW_ELEMENT: 1, SHOW_ATTRIBUTE: 2, SHOW_TEXT: 4, SHOW_CDATA_SECTION: 8, SHOW_ENTITY_REFERENCE: 16, SHOW_ENTITY: 32, SHOW_PROCESSING_INSTRUCTION: 64, SHOW_COMMENT: 128, SHOW_DOCUMENT: 256, SHOW_DOCUMENT_TYPE: 512, SHOW_DOCUMENT_FRAGMENT: 1024, SHOW_NOTATION: 2048, } ) class NodeIterator$1 { nextNode() { return null } previousNode() { return null } get filter() { const internals = internalsOf(this, 'NodeIterator', 'filter') return internals.filter } get pointerBeforeReferenceNode() { const internals = internalsOf( this, 'NodeIterator', 'pointerBeforeReferenceNode' ) return internals.pointerBeforeReferenceNode } get referenceNode() { const internals = internalsOf(this, 'NodeIterator', 'referenceNode') return internals.referenceNode } get root() { const internals = internalsOf(this, 'NodeIterator', 'root') return internals.root } get whatToShow() { const internals = internalsOf(this, 'NodeIterator', 'whatToShow') return internals.whatToShow } } allowStringTag(Node) allowStringTag(NodeIterator$1) allowStringTag(DocumentFragment) allowStringTag(ShadowRoot) class CharacterData extends Node { constructor(data) { INTERNALS$3.set(super(), { data: String(data), }) } get data() { return internalsOf(this, 'CharacterData', 'data').data } get textContent() { return internalsOf(this, 'CharacterData', 'textContent').data } } class Comment extends CharacterData {} class Text extends CharacterData { get assignedSlot() { return null } get wholeText() { return internalsOf(this, 'CharacterData', 'textContent').data } } allowStringTag(CharacterData) allowStringTag(Text) allowStringTag(Comment) /** * web-streams-polyfill v3.2.0 */ /// const SymbolPolyfill = Symbol /// function noop$1() { return undefined } function typeIsObject(x) { return (typeof x === 'object' && x !== null) || typeof x === 'function' } const rethrowAssertionErrorRejection = noop$1 const originalPromise = Promise const originalPromiseThen = Promise.prototype.then const originalPromiseResolve = Promise.resolve.bind(originalPromise) const originalPromiseReject = Promise.reject.bind(originalPromise) function newPromise(executor) { return new originalPromise(executor) } function promiseResolvedWith(value) { return originalPromiseResolve(value) } function promiseRejectedWith(reason) { return originalPromiseReject(reason) } function PerformPromiseThen(promise, onFulfilled, onRejected) { // There doesn't appear to be any way to correctly emulate the behaviour from JavaScript, so this is just an // approximation. return originalPromiseThen.call(promise, onFulfilled, onRejected) } function uponPromise(promise, onFulfilled, onRejected) { PerformPromiseThen( PerformPromiseThen(promise, onFulfilled, onRejected), undefined, rethrowAssertionErrorRejection ) } function uponFulfillment(promise, onFulfilled) { uponPromise(promise, onFulfilled) } function uponRejection(promise, onRejected) { uponPromise(promise, undefined, onRejected) } function transformPromiseWith(promise, fulfillmentHandler, rejectionHandler) { return PerformPromiseThen(promise, fulfillmentHandler, rejectionHandler) } function setPromiseIsHandledToTrue(promise) { PerformPromiseThen(promise, undefined, rethrowAssertionErrorRejection) } function reflectCall(F, V, args) { if (typeof F !== 'function') { throw new TypeError('Argument is not a function') } return Function.prototype.apply.call(F, V, args) } function promiseCall(F, V, args) { try { return promiseResolvedWith(reflectCall(F, V, args)) } catch (value) { return promiseRejectedWith(value) } } // Original from Chromium // https://chromium.googlesource.com/chromium/src/+/0aee4434a4dba42a42abaea9bfbc0cd196a63bc1/third_party/blink/renderer/core/streams/SimpleQueue.js const QUEUE_MAX_ARRAY_SIZE = 16384 /** * Simple queue structure. * * Avoids scalability issues with using a packed array directly by using * multiple arrays in a linked list and keeping the array size bounded. */ class SimpleQueue { constructor() { this._cursor = 0 this._size = 0 // _front and _back are always defined. this._front = { _elements: [], _next: undefined, } this._back = this._front // The cursor is used to avoid calling Array.shift(). // It contains the index of the front element of the array inside the // front-most node. It is always in the range [0, QUEUE_MAX_ARRAY_SIZE). this._cursor = 0 // When there is only one node, size === elements.length - cursor. this._size = 0 } get length() { return this._size } // For exception safety, this method is structured in order: // 1. Read state // 2. Calculate required state mutations // 3. Perform state mutations push(element) { const oldBack = this._back let newBack = oldBack if (oldBack._elements.length === QUEUE_MAX_ARRAY_SIZE - 1) { newBack = { _elements: [], _next: undefined, } } // push() is the mutation most likely to throw an exception, so it // goes first. oldBack._elements.push(element) if (newBack !== oldBack) { this._back = newBack oldBack._next = newBack } ++this._size } // Like push(), shift() follows the read -> calculate -> mutate pattern for // exception safety. shift() { // must not be called on an empty queue const oldFront = this._front let newFront = oldFront const oldCursor = this._cursor let newCursor = oldCursor + 1 const elements = oldFront._elements const element = elements[oldCursor] if (newCursor === QUEUE_MAX_ARRAY_SIZE) { newFront = oldFront._next newCursor = 0 } // No mutations before this point. --this._size this._cursor = newCursor if (oldFront !== newFront) { this._front = newFront } // Permit shifted element to be garbage collected. elements[oldCursor] = undefined return element } // The tricky thing about forEach() is that it can be called // re-entrantly. The queue may be mutated inside the callback. It is easy to // see that push() within the callback has no negative effects since the end // of the queue is checked for on every iteration. If shift() is called // repeatedly within the callback then the next iteration may return an // element that has been removed. In this case the callback will be called // with undefined values until we either "catch up" with elements that still // exist or reach the back of the queue. forEach(callback) { let i = this._cursor let node = this._front let elements = node._elements while (i !== elements.length || node._next !== undefined) { if (i === elements.length) { node = node._next elements = node._elements i = 0 if (elements.length === 0) { break } } callback(elements[i]) ++i } } // Return the element that would be returned if shift() was called now, // without modifying the queue. peek() { // must not be called on an empty queue const front = this._front const cursor = this._cursor return front._elements[cursor] } } function ReadableStreamReaderGenericInitialize(reader, stream) { reader._ownerReadableStream = stream stream._reader = reader if (stream._state === 'readable') { defaultReaderClosedPromiseInitialize(reader) } else if (stream._state === 'closed') { defaultReaderClosedPromiseInitializeAsResolved(reader) } else { defaultReaderClosedPromiseInitializeAsRejected(reader, stream._storedError) } } // A client of ReadableStreamDefaultReader and ReadableStreamBYOBReader may use these functions directly to bypass state // check. function ReadableStreamReaderGenericCancel(reader, reason) { const stream = reader._ownerReadableStream return ReadableStreamCancel(stream, reason) } function ReadableStreamReaderGenericRelease(reader) { if (reader._ownerReadableStream._state === 'readable') { defaultReaderClosedPromiseReject( reader, new TypeError( `Reader was released and can no longer be used to monitor the stream's closedness` ) ) } else { defaultReaderClosedPromiseResetToRejected( reader, new TypeError( `Reader was released and can no longer be used to monitor the stream's closedness` ) ) } reader._ownerReadableStream._reader = undefined reader._ownerReadableStream = undefined } // Helper functions for the readers. function readerLockException(name) { return new TypeError('Cannot ' + name + ' a stream using a released reader') } // Helper functions for the ReadableStreamDefaultReader. function defaultReaderClosedPromiseInitialize(reader) { reader._closedPromise = newPromise((resolve, reject) => { reader._closedPromise_resolve = resolve reader._closedPromise_reject = reject }) } function defaultReaderClosedPromiseInitializeAsRejected(reader, reason) { defaultReaderClosedPromiseInitialize(reader) defaultReaderClosedPromiseReject(reader, reason) } function defaultReaderClosedPromiseInitializeAsResolved(reader) { defaultReaderClosedPromiseInitialize(reader) defaultReaderClosedPromiseResolve(reader) } function defaultReaderClosedPromiseReject(reader, reason) { if (reader._closedPromise_reject === undefined) { return } setPromiseIsHandledToTrue(reader._closedPromise) reader._closedPromise_reject(reason) reader._closedPromise_resolve = undefined reader._closedPromise_reject = undefined } function defaultReaderClosedPromiseResetToRejected(reader, reason) { defaultReaderClosedPromiseInitializeAsRejected(reader, reason) } function defaultReaderClosedPromiseResolve(reader) { if (reader._closedPromise_resolve === undefined) { return } reader._closedPromise_resolve(undefined) reader._closedPromise_resolve = undefined reader._closedPromise_reject = undefined } const AbortSteps = SymbolPolyfill('[[AbortSteps]]') const ErrorSteps = SymbolPolyfill('[[ErrorSteps]]') const CancelSteps = SymbolPolyfill('[[CancelSteps]]') const PullSteps = SymbolPolyfill('[[PullSteps]]') /// // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite#Polyfill const NumberIsFinite = Number.isFinite || function (x) { return typeof x === 'number' && isFinite(x) } /// // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc#Polyfill const MathTrunc = Math.trunc || function (v) { return v < 0 ? Math.ceil(v) : Math.floor(v) } // https://heycam.github.io/webidl/#idl-dictionaries function isDictionary(x) { return typeof x === 'object' || typeof x === 'function' } function assertDictionary(obj, context) { if (obj !== undefined && !isDictionary(obj)) { throw new TypeError(`${context} is not an object.`) } } // https://heycam.github.io/webidl/#idl-callback-functions function assertFunction(x, context) { if (typeof x !== 'function') { throw new TypeError(`${context} is not a function.`) } } // https://heycam.github.io/webidl/#idl-object function isObject(x) { return (typeof x === 'object' && x !== null) || typeof x === 'function' } function assertObject(x, context) { if (!isObject(x)) { throw new TypeError(`${context} is not an object.`) } } function assertRequiredArgument(x, position, context) { if (x === undefined) { throw new TypeError(`Parameter ${position} is required in '${context}'.`) } } function assertRequiredField(x, field, context) { if (x === undefined) { throw new TypeError(`${field} is required in '${context}'.`) } } // https://heycam.github.io/webidl/#idl-unrestricted-double function convertUnrestrictedDouble(value) { return Number(value) } function censorNegativeZero(x) { return x === 0 ? 0 : x } function integerPart(x) { return censorNegativeZero(MathTrunc(x)) } // https://heycam.github.io/webidl/#idl-unsigned-long-long function convertUnsignedLongLongWithEnforceRange(value, context) { const lowerBound = 0 const upperBound = Number.MAX_SAFE_INTEGER let x = Number(value) x = censorNegativeZero(x) if (!NumberIsFinite(x)) { throw new TypeError(`${context} is not a finite number`) } x = integerPart(x) if (x < lowerBound || x > upperBound) { throw new TypeError( `${context} is outside the accepted range of ${lowerBound} to ${upperBound}, inclusive` ) } if (!NumberIsFinite(x) || x === 0) { return 0 } // TODO Use BigInt if supported? // let xBigInt = BigInt(integerPart(x)); // xBigInt = BigInt.asUintN(64, xBigInt); // return Number(xBigInt); return x } function assertReadableStream(x, context) { if (!IsReadableStream(x)) { throw new TypeError(`${context} is not a ReadableStream.`) } } // Abstract operations for the ReadableStream. function AcquireReadableStreamDefaultReader(stream) { return new ReadableStreamDefaultReader(stream) } // ReadableStream API exposed for controllers. function ReadableStreamAddReadRequest(stream, readRequest) { stream._reader._readRequests.push(readRequest) } function ReadableStreamFulfillReadRequest(stream, chunk, done) { const reader = stream._reader const readRequest = reader._readRequests.shift() if (done) { readRequest._closeSteps() } else { readRequest._chunkSteps(chunk) } } function ReadableStreamGetNumReadRequests(stream) { return stream._reader._readRequests.length } function ReadableStreamHasDefaultReader(stream) { const reader = stream._reader if (reader === undefined) { return false } if (!IsReadableStreamDefaultReader(reader)) { return false } return true } /** * A default reader vended by a {@link ReadableStream}. * * @public */ class ReadableStreamDefaultReader { constructor(stream) { assertRequiredArgument(stream, 1, 'ReadableStreamDefaultReader') assertReadableStream(stream, 'First parameter') if (IsReadableStreamLocked(stream)) { throw new TypeError( 'This stream has already been locked for exclusive reading by another reader' ) } ReadableStreamReaderGenericInitialize(this, stream) this._readRequests = new SimpleQueue() } /** * Returns a promise that will be fulfilled when the stream becomes closed, * or rejected if the stream ever errors or the reader's lock is released before the stream finishes closing. */ get closed() { if (!IsReadableStreamDefaultReader(this)) { return promiseRejectedWith(defaultReaderBrandCheckException('closed')) } return this._closedPromise } /** * If the reader is active, behaves the same as {@link ReadableStream.cancel | stream.cancel(reason)}. */ cancel(reason = undefined) { if (!IsReadableStreamDefaultReader(this)) { return promiseRejectedWith(defaultReaderBrandCheckException('cancel')) } if (this._ownerReadableStream === undefined) { return promiseRejectedWith(readerLockException('cancel')) } return ReadableStreamReaderGenericCancel(this, reason) } /** * Returns a promise that allows access to the next chunk from the stream's internal queue, if available. * * If reading a chunk causes the queue to become empty, more data will be pulled from the underlying source. */ read() { if (!IsReadableStreamDefaultReader(this)) { return promiseRejectedWith(defaultReaderBrandCheckException('read')) } if (this._ownerReadableStream === undefined) { return promiseRejectedWith(readerLockException('read from')) } let resolvePromise let rejectPromise const promise = newPromise((resolve, reject) => { resolvePromise = resolve rejectPromise = reject }) const readRequest = { _chunkSteps: (chunk) => resolvePromise({ value: chunk, done: false }), _closeSteps: () => resolvePromise({ value: undefined, done: true }), _errorSteps: (e) => rejectPromise(e), } ReadableStreamDefaultReaderRead(this, readRequest) return promise } /** * Releases the reader's lock on the corresponding stream. After the lock is released, the reader is no longer active. * If the associated stream is errored when the lock is released, the reader will appear errored in the same way * from now on; otherwise, the reader will appear closed. * * A reader's lock cannot be released while it still has a pending read request, i.e., if a promise returned by * the reader's {@link ReadableStreamDefaultReader.read | read()} method has not yet been settled. Attempting to * do so will throw a `TypeError` and leave the reader locked to the stream. */ releaseLock() { if (!IsReadableStreamDefaultReader(this)) { throw defaultReaderBrandCheckException('releaseLock') } if (this._ownerReadableStream === undefined) { return } if (this._readRequests.length > 0) { throw new TypeError( 'Tried to release a reader lock when that reader has pending read() calls un-settled' ) } ReadableStreamReaderGenericRelease(this) } } Object.defineProperties(ReadableStreamDefaultReader.prototype, { cancel: { enumerable: true }, read: { enumerable: true }, releaseLock: { enumerable: true }, closed: { enumerable: true }, }) // Abstract operations for the readers. function IsReadableStreamDefaultReader(x) { if (!typeIsObject(x)) { return false } if (!Object.prototype.hasOwnProperty.call(x, '_readRequests')) { return false } return x instanceof ReadableStreamDefaultReader } function ReadableStreamDefaultReaderRead(reader, readRequest) { const stream = reader._ownerReadableStream stream._disturbed = true if (stream._state === 'closed') { readRequest._closeSteps() } else if (stream._state === 'errored') { readRequest._errorSteps(stream._storedError) } else { stream._readableStreamController[PullSteps](readRequest) } } // Helper functions for the ReadableStreamDefaultReader. function defaultReaderBrandCheckException(name) { return new TypeError( `ReadableStreamDefaultReader.prototype.${name} can only be used on a ReadableStreamDefaultReader` ) } /// class ReadableStreamAsyncIteratorImpl { constructor(reader, preventCancel) { this._ongoingPromise = undefined this._isFinished = false this._reader = reader this._preventCancel = preventCancel } next() { const nextSteps = () => this._nextSteps() this._ongoingPromise = this._ongoingPromise ? transformPromiseWith(this._ongoingPromise, nextSteps, nextSteps) : nextSteps() return this._ongoingPromise } return(value) { const returnSteps = () => this._returnSteps(value) return this._ongoingPromise ? transformPromiseWith(this._ongoingPromise, returnSteps, returnSteps) : returnSteps() } _nextSteps() { if (this._isFinished) { return Promise.resolve({ value: undefined, done: true }) } const reader = this._reader if (reader._ownerReadableStream === undefined) { return promiseRejectedWith(readerLockException('iterate')) } let resolvePromise let rejectPromise const promise = newPromise((resolve, reject) => { resolvePromise = resolve rejectPromise = reject }) const readRequest = { _chunkSteps: (chunk) => { this._ongoingPromise = undefined // This needs to be delayed by one microtask, otherwise we stop pulling too early which breaks a test. // FIXME Is this a bug in the specification, or in the test? queueMicrotask(() => resolvePromise({ value: chunk, done: false })) }, _closeSteps: () => { this._ongoingPromise = undefined this._isFinished = true ReadableStreamReaderGenericRelease(reader) resolvePromise({ value: undefined, done: true }) }, _errorSteps: (reason) => { this._ongoingPromise = undefined this._isFinished = true ReadableStreamReaderGenericRelease(reader) rejectPromise(reason) }, } ReadableStreamDefaultReaderRead(reader, readRequest) return promise } _returnSteps(value) { if (this._isFinished) { return Promise.resolve({ value, done: true }) } this._isFinished = true const reader = this._reader if (reader._ownerReadableStream === undefined) { return promiseRejectedWith(readerLockException('finish iterating')) } if (!this._preventCancel) { const result = ReadableStreamReaderGenericCancel(reader, value) ReadableStreamReaderGenericRelease(reader) return transformPromiseWith(result, () => ({ value, done: true })) } ReadableStreamReaderGenericRelease(reader) return promiseResolvedWith({ value, done: true }) } } const ReadableStreamAsyncIteratorPrototype = { next() { if (!IsReadableStreamAsyncIterator(this)) { return promiseRejectedWith(streamAsyncIteratorBrandCheckException('next')) } return this._asyncIteratorImpl.next() }, return(value) { if (!IsReadableStreamAsyncIterator(this)) { return promiseRejectedWith( streamAsyncIteratorBrandCheckException('return') ) } return this._asyncIteratorImpl.return(value) }, } // Abstract operations for the ReadableStream. function AcquireReadableStreamAsyncIterator(stream, preventCancel) { const reader = AcquireReadableStreamDefaultReader(stream) const impl = new ReadableStreamAsyncIteratorImpl(reader, preventCancel) const iterator = Object.create(ReadableStreamAsyncIteratorPrototype) iterator._asyncIteratorImpl = impl return iterator } function IsReadableStreamAsyncIterator(x) { if (!typeIsObject(x)) { return false } if (!Object.prototype.hasOwnProperty.call(x, '_asyncIteratorImpl')) { return false } try { // noinspection SuspiciousTypeOfGuard return x._asyncIteratorImpl instanceof ReadableStreamAsyncIteratorImpl } catch (_a) { return false } } // Helper functions for the ReadableStream. function streamAsyncIteratorBrandCheckException(name) { return new TypeError( `ReadableStreamAsyncIterator.${name} can only be used on a ReadableSteamAsyncIterator` ) } /// // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN#Polyfill const NumberIsNaN = Number.isNaN || function (x) { // eslint-disable-next-line no-self-compare return x !== x } function CreateArrayFromList(elements) { // We use arrays to represent lists, so this is basically a no-op. // Do a slice though just in case we happen to depend on the unique-ness. return elements.slice() } function CopyDataBlockBytes(dest, destOffset, src, srcOffset, n) { new Uint8Array(dest).set(new Uint8Array(src, srcOffset, n), destOffset) } // Not implemented correctly function TransferArrayBuffer(O) { return O } // Not implemented correctly // eslint-disable-next-line @typescript-eslint/no-unused-vars function IsDetachedBuffer(O) { return false } function ArrayBufferSlice(buffer, begin, end) { // ArrayBuffer.prototype.slice is not available on IE10 // https://www.caniuse.com/mdn-javascript_builtins_arraybuffer_slice if (buffer.slice) { return buffer.slice(begin, end) } const length = end - begin const slice = new ArrayBuffer(length) CopyDataBlockBytes(slice, 0, buffer, begin, length) return slice } function IsNonNegativeNumber(v) { if (typeof v !== 'number') { return false } if (NumberIsNaN(v)) { return false } if (v < 0) { return false } return true } function CloneAsUint8Array(O) { const buffer = ArrayBufferSlice( O.buffer, O.byteOffset, O.byteOffset + O.byteLength ) return new Uint8Array(buffer) } function DequeueValue(container) { const pair = container._queue.shift() container._queueTotalSize -= pair.size if (container._queueTotalSize < 0) { container._queueTotalSize = 0 } return pair.value } function EnqueueValueWithSize(container, value, size) { if (!IsNonNegativeNumber(size) || size === Infinity) { throw new RangeError('Size must be a finite, non-NaN, non-negative number.') } container._queue.push({ value, size }) container._queueTotalSize += size } function PeekQueueValue(container) { const pair = container._queue.peek() return pair.value } function ResetQueue(container) { container._queue = new SimpleQueue() container._queueTotalSize = 0 } /** * A pull-into request in a {@link ReadableByteStreamController}. * * @public */ class ReadableStreamBYOBRequest { constructor() { throw new TypeError('Illegal constructor') } /** * Returns the view for writing in to, or `null` if the BYOB request has already been responded to. */ get view() { if (!IsReadableStreamBYOBRequest(this)) { throw byobRequestBrandCheckException('view') } return this._view } respond(bytesWritten) { if (!IsReadableStreamBYOBRequest(this)) { throw byobRequestBrandCheckException('respond') } assertRequiredArgument(bytesWritten, 1, 'respond') bytesWritten = convertUnsignedLongLongWithEnforceRange( bytesWritten, 'First parameter' ) if (this._associatedReadableByteStreamController === undefined) { throw new TypeError('This BYOB request has been invalidated') } if (IsDetachedBuffer(this._view.buffer)); ReadableByteStreamControllerRespond( this._associatedReadableByteStreamController, bytesWritten ) } respondWithNewView(view) { if (!IsReadableStreamBYOBRequest(this)) { throw byobRequestBrandCheckException('respondWithNewView') } assertRequiredArgument(view, 1, 'respondWithNewView') if (!ArrayBuffer.isView(view)) { throw new TypeError('You can only respond with array buffer views') } if (this._associatedReadableByteStreamController === undefined) { throw new TypeError('This BYOB request has been invalidated') } if (IsDetachedBuffer(view.buffer)); ReadableByteStreamControllerRespondWithNewView( this._associatedReadableByteStreamController, view ) } } Object.defineProperties(ReadableStreamBYOBRequest.prototype, { respond: { enumerable: true }, respondWithNewView: { enumerable: true }, view: { enumerable: true }, }) /** * Allows control of a {@link ReadableStream | readable byte stream}'s state and internal queue. * * @public */ class ReadableByteStreamController { constructor() { throw new TypeError('Illegal constructor') } /** * Returns the current BYOB pull request, or `null` if there isn't one. */ get byobRequest() { if (!IsReadableByteStreamController(this)) { throw byteStreamControllerBrandCheckException('byobRequest') } return ReadableByteStreamControllerGetBYOBRequest(this) } /** * Returns the desired size to fill the controlled stream's internal queue. It can be negative, if the queue is * over-full. An underlying byte source ought to use this information to determine when and how to apply backpressure. */ get desiredSize() { if (!IsReadableByteStreamController(this)) { throw byteStreamControllerBrandCheckException('desiredSize') } return ReadableByteStreamControllerGetDesiredSize(this) } /** * Closes the controlled readable stream. Consumers will still be able to read any previously-enqueued chunks from * the stream, but once those are read, the stream will become closed. */ close() { if (!IsReadableByteStreamController(this)) { throw byteStreamControllerBrandCheckException('close') } if (this._closeRequested) { throw new TypeError( 'The stream has already been closed; do not close it again!' ) } const state = this._controlledReadableByteStream._state if (state !== 'readable') { throw new TypeError( `The stream (in ${state} state) is not in the readable state and cannot be closed` ) } ReadableByteStreamControllerClose(this) } enqueue(chunk) { if (!IsReadableByteStreamController(this)) { throw byteStreamControllerBrandCheckException('enqueue') } assertRequiredArgument(chunk, 1, 'enqueue') if (!ArrayBuffer.isView(chunk)) { throw new TypeError('chunk must be an array buffer view') } if (chunk.byteLength === 0) { throw new TypeError('chunk must have non-zero byteLength') } if (chunk.buffer.byteLength === 0) { throw new TypeError(`chunk's buffer must have non-zero byteLength`) } if (this._closeRequested) { throw new TypeError('stream is closed or draining') } const state = this._controlledReadableByteStream._state if (state !== 'readable') { throw new TypeError( `The stream (in ${state} state) is not in the readable state and cannot be enqueued to` ) } ReadableByteStreamControllerEnqueue(this, chunk) } /** * Errors the controlled readable stream, making all future interactions with it fail with the given error `e`. */ error(e = undefined) { if (!IsReadableByteStreamController(this)) { throw byteStreamControllerBrandCheckException('error') } ReadableByteStreamControllerError(this, e) } /** @internal */ [CancelSteps](reason) { ReadableByteStreamControllerClearPendingPullIntos(this) ResetQueue(this) const result = this._cancelAlgorithm(reason) ReadableByteStreamControllerClearAlgorithms(this) return result } /** @internal */ [PullSteps](readRequest) { const stream = this._controlledReadableByteStream if (this._queueTotalSize > 0) { const entry = this._queue.shift() this._queueTotalSize -= entry.byteLength ReadableByteStreamControllerHandleQueueDrain(this) const view = new Uint8Array( entry.buffer, entry.byteOffset, entry.byteLength ) readRequest._chunkSteps(view) return } const autoAllocateChunkSize = this._autoAllocateChunkSize if (autoAllocateChunkSize !== undefined) { let buffer try { buffer = new ArrayBuffer(autoAllocateChunkSize) } catch (bufferE) { readRequest._errorSteps(bufferE) return } const pullIntoDescriptor = { buffer, bufferByteLength: autoAllocateChunkSize, byteOffset: 0, byteLength: autoAllocateChunkSize, bytesFilled: 0, elementSize: 1, viewConstructor: Uint8Array, readerType: 'default', } this._pendingPullIntos.push(pullIntoDescriptor) } ReadableStreamAddReadRequest(stream, readRequest) ReadableByteStreamControllerCallPullIfNeeded(this) } } Object.defineProperties(ReadableByteStreamController.prototype, { close: { enumerable: true }, enqueue: { enumerable: true }, error: { enumerable: true }, byobRequest: { enumerable: true }, desiredSize: { enumerable: true }, }) // Abstract operations for the ReadableByteStreamController. function IsReadableByteStreamController(x) { if (!typeIsObject(x)) { return false } if ( !Object.prototype.hasOwnProperty.call(x, '_controlledReadableByteStream') ) { return false } return x instanceof ReadableByteStreamController } function IsReadableStreamBYOBRequest(x) { if (!typeIsObject(x)) { return false } if ( !Object.prototype.hasOwnProperty.call( x, '_associatedReadableByteStreamController' ) ) { return false } return x instanceof ReadableStreamBYOBRequest } function ReadableByteStreamControllerCallPullIfNeeded(controller) { const shouldPull = ReadableByteStreamControllerShouldCallPull(controller) if (!shouldPull) { return } if (controller._pulling) { controller._pullAgain = true return } controller._pulling = true // TODO: Test controller argument const pullPromise = controller._pullAlgorithm() uponPromise( pullPromise, () => { controller._pulling = false if (controller._pullAgain) { controller._pullAgain = false ReadableByteStreamControllerCallPullIfNeeded(controller) } }, (e) => { ReadableByteStreamControllerError(controller, e) } ) } function ReadableByteStreamControllerClearPendingPullIntos(controller) { ReadableByteStreamControllerInvalidateBYOBRequest(controller) controller._pendingPullIntos = new SimpleQueue() } function ReadableByteStreamControllerCommitPullIntoDescriptor( stream, pullIntoDescriptor ) { let done = false if (stream._state === 'closed') { done = true } const filledView = ReadableByteStreamControllerConvertPullIntoDescriptor(pullIntoDescriptor) if (pullIntoDescriptor.readerType === 'default') { ReadableStreamFulfillReadRequest(stream, filledView, done) } else { ReadableStreamFulfillReadIntoRequest(stream, filledView, done) } } function ReadableByteStreamControllerConvertPullIntoDescriptor( pullIntoDescriptor ) { const bytesFilled = pullIntoDescriptor.bytesFilled const elementSize = pullIntoDescriptor.elementSize return new pullIntoDescriptor.viewConstructor( pullIntoDescriptor.buffer, pullIntoDescriptor.byteOffset, bytesFilled / elementSize ) } function ReadableByteStreamControllerEnqueueChunkToQueue( controller, buffer, byteOffset, byteLength ) { controller._queue.push({ buffer, byteOffset, byteLength }) controller._queueTotalSize += byteLength } function ReadableByteStreamControllerFillPullIntoDescriptorFromQueue( controller, pullIntoDescriptor ) { const elementSize = pullIntoDescriptor.elementSize const currentAlignedBytes = pullIntoDescriptor.bytesFilled - (pullIntoDescriptor.bytesFilled % elementSize) const maxBytesToCopy = Math.min( controller._queueTotalSize, pullIntoDescriptor.byteLength - pullIntoDescriptor.bytesFilled ) const maxBytesFilled = pullIntoDescriptor.bytesFilled + maxBytesToCopy const maxAlignedBytes = maxBytesFilled - (maxBytesFilled % elementSize) let totalBytesToCopyRemaining = maxBytesToCopy let ready = false if (maxAlignedBytes > currentAlignedBytes) { totalBytesToCopyRemaining = maxAlignedBytes - pullIntoDescriptor.bytesFilled ready = true } const queue = controller._queue while (totalBytesToCopyRemaining > 0) { const headOfQueue = queue.peek() const bytesToCopy = Math.min( totalBytesToCopyRemaining, headOfQueue.byteLength ) const destStart = pullIntoDescriptor.byteOffset + pullIntoDescriptor.bytesFilled CopyDataBlockBytes( pullIntoDescriptor.buffer, destStart, headOfQueue.buffer, headOfQueue.byteOffset, bytesToCopy ) if (headOfQueue.byteLength === bytesToCopy) { queue.shift() } else { headOfQueue.byteOffset += bytesToCopy headOfQueue.byteLength -= bytesToCopy } controller._queueTotalSize -= bytesToCopy ReadableByteStreamControllerFillHeadPullIntoDescriptor( controller, bytesToCopy, pullIntoDescriptor ) totalBytesToCopyRemaining -= bytesToCopy } return ready } function ReadableByteStreamControllerFillHeadPullIntoDescriptor( controller, size, pullIntoDescriptor ) { pullIntoDescriptor.bytesFilled += size } function ReadableByteStreamControllerHandleQueueDrain(controller) { if (controller._queueTotalSize === 0 && controller._closeRequested) { ReadableByteStreamControllerClearAlgorithms(controller) ReadableStreamClose(controller._controlledReadableByteStream) } else { ReadableByteStreamControllerCallPullIfNeeded(controller) } } function ReadableByteStreamControllerInvalidateBYOBRequest(controller) { if (controller._byobRequest === null) { return } controller._byobRequest._associatedReadableByteStreamController = undefined controller._byobRequest._view = null controller._byobRequest = null } function ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue( controller ) { while (controller._pendingPullIntos.length > 0) { if (controller._queueTotalSize === 0) { return } const pullIntoDescriptor = controller._pendingPullIntos.peek() if ( ReadableByteStreamControllerFillPullIntoDescriptorFromQueue( controller, pullIntoDescriptor ) ) { ReadableByteStreamControllerShiftPendingPullInto(controller) ReadableByteStreamControllerCommitPullIntoDescriptor( controller._controlledReadableByteStream, pullIntoDescriptor ) } } } function ReadableByteStreamControllerPullInto( controller, view, readIntoRequest ) { const stream = controller._controlledReadableByteStream let elementSize = 1 if (view.constructor !== DataView) { elementSize = view.constructor.BYTES_PER_ELEMENT } const ctor = view.constructor // try { const buffer = TransferArrayBuffer(view.buffer) // } catch (e) { // readIntoRequest._errorSteps(e); // return; // } const pullIntoDescriptor = { buffer, bufferByteLength: buffer.byteLength, byteOffset: view.byteOffset, byteLength: view.byteLength, bytesFilled: 0, elementSize, viewConstructor: ctor, readerType: 'byob', } if (controller._pendingPullIntos.length > 0) { controller._pendingPullIntos.push(pullIntoDescriptor) // No ReadableByteStreamControllerCallPullIfNeeded() call since: // - No change happens on desiredSize // - The source has already been notified of that there's at least 1 pending read(view) ReadableStreamAddReadIntoRequest(stream, readIntoRequest) return } if (stream._state === 'closed') { const emptyView = new ctor( pullIntoDescriptor.buffer, pullIntoDescriptor.byteOffset, 0 ) readIntoRequest._closeSteps(emptyView) return } if (controller._queueTotalSize > 0) { if ( ReadableByteStreamControllerFillPullIntoDescriptorFromQueue( controller, pullIntoDescriptor ) ) { const filledView = ReadableByteStreamControllerConvertPullIntoDescriptor( pullIntoDescriptor ) ReadableByteStreamControllerHandleQueueDrain(controller) readIntoRequest._chunkSteps(filledView) return } if (controller._closeRequested) { const e = new TypeError( 'Insufficient bytes to fill elements in the given buffer' ) ReadableByteStreamControllerError(controller, e) readIntoRequest._errorSteps(e) return } } controller._pendingPullIntos.push(pullIntoDescriptor) ReadableStreamAddReadIntoRequest(stream, readIntoRequest) ReadableByteStreamControllerCallPullIfNeeded(controller) } function ReadableByteStreamControllerRespondInClosedState( controller, firstDescriptor ) { const stream = controller._controlledReadableByteStream if (ReadableStreamHasBYOBReader(stream)) { while (ReadableStreamGetNumReadIntoRequests(stream) > 0) { const pullIntoDescriptor = ReadableByteStreamControllerShiftPendingPullInto(controller) ReadableByteStreamControllerCommitPullIntoDescriptor( stream, pullIntoDescriptor ) } } } function ReadableByteStreamControllerRespondInReadableState( controller, bytesWritten, pullIntoDescriptor ) { ReadableByteStreamControllerFillHeadPullIntoDescriptor( controller, bytesWritten, pullIntoDescriptor ) if (pullIntoDescriptor.bytesFilled < pullIntoDescriptor.elementSize) { return } ReadableByteStreamControllerShiftPendingPullInto(controller) const remainderSize = pullIntoDescriptor.bytesFilled % pullIntoDescriptor.elementSize if (remainderSize > 0) { const end = pullIntoDescriptor.byteOffset + pullIntoDescriptor.bytesFilled const remainder = ArrayBufferSlice( pullIntoDescriptor.buffer, end - remainderSize, end ) ReadableByteStreamControllerEnqueueChunkToQueue( controller, remainder, 0, remainder.byteLength ) } pullIntoDescriptor.bytesFilled -= remainderSize ReadableByteStreamControllerCommitPullIntoDescriptor( controller._controlledReadableByteStream, pullIntoDescriptor ) ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller) } function ReadableByteStreamControllerRespondInternal(controller, bytesWritten) { const firstDescriptor = controller._pendingPullIntos.peek() ReadableByteStreamControllerInvalidateBYOBRequest(controller) const state = controller._controlledReadableByteStream._state if (state === 'closed') { ReadableByteStreamControllerRespondInClosedState(controller) } else { ReadableByteStreamControllerRespondInReadableState( controller, bytesWritten, firstDescriptor ) } ReadableByteStreamControllerCallPullIfNeeded(controller) } function ReadableByteStreamControllerShiftPendingPullInto(controller) { const descriptor = controller._pendingPullIntos.shift() return descriptor } function ReadableByteStreamControllerShouldCallPull(controller) { const stream = controller._controlledReadableByteStream if (stream._state !== 'readable') { return false } if (controller._closeRequested) { return false } if (!controller._started) { return false } if ( ReadableStreamHasDefaultReader(stream) && ReadableStreamGetNumReadRequests(stream) > 0 ) { return true } if ( ReadableStreamHasBYOBReader(stream) && ReadableStreamGetNumReadIntoRequests(stream) > 0 ) { return true } const desiredSize = ReadableByteStreamControllerGetDesiredSize(controller) if (desiredSize > 0) { return true } return false } function ReadableByteStreamControllerClearAlgorithms(controller) { controller._pullAlgorithm = undefined controller._cancelAlgorithm = undefined } // A client of ReadableByteStreamController may use these functions directly to bypass state check. function ReadableByteStreamControllerClose(controller) { const stream = controller._controlledReadableByteStream if (controller._closeRequested || stream._state !== 'readable') { return } if (controller._queueTotalSize > 0) { controller._closeRequested = true return } if (controller._pendingPullIntos.length > 0) { const firstPendingPullInto = controller._pendingPullIntos.peek() if (firstPendingPullInto.bytesFilled > 0) { const e = new TypeError( 'Insufficient bytes to fill elements in the given buffer' ) ReadableByteStreamControllerError(controller, e) throw e } } ReadableByteStreamControllerClearAlgorithms(controller) ReadableStreamClose(stream) } function ReadableByteStreamControllerEnqueue(controller, chunk) { const stream = controller._controlledReadableByteStream if (controller._closeRequested || stream._state !== 'readable') { return } const buffer = chunk.buffer const byteOffset = chunk.byteOffset const byteLength = chunk.byteLength const transferredBuffer = TransferArrayBuffer(buffer) if (controller._pendingPullIntos.length > 0) { const firstPendingPullInto = controller._pendingPullIntos.peek() if (IsDetachedBuffer(firstPendingPullInto.buffer)); firstPendingPullInto.buffer = TransferArrayBuffer( firstPendingPullInto.buffer ) } ReadableByteStreamControllerInvalidateBYOBRequest(controller) if (ReadableStreamHasDefaultReader(stream)) { if (ReadableStreamGetNumReadRequests(stream) === 0) { ReadableByteStreamControllerEnqueueChunkToQueue( controller, transferredBuffer, byteOffset, byteLength ) } else { if (controller._pendingPullIntos.length > 0) { ReadableByteStreamControllerShiftPendingPullInto(controller) } const transferredView = new Uint8Array( transferredBuffer, byteOffset, byteLength ) ReadableStreamFulfillReadRequest(stream, transferredView, false) } } else if (ReadableStreamHasBYOBReader(stream)) { // TODO: Ideally in this branch detaching should happen only if the buffer is not consumed fully. ReadableByteStreamControllerEnqueueChunkToQueue( controller, transferredBuffer, byteOffset, byteLength ) ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller) } else { ReadableByteStreamControllerEnqueueChunkToQueue( controller, transferredBuffer, byteOffset, byteLength ) } ReadableByteStreamControllerCallPullIfNeeded(controller) } function ReadableByteStreamControllerError(controller, e) { const stream = controller._controlledReadableByteStream if (stream._state !== 'readable') { return } ReadableByteStreamControllerClearPendingPullIntos(controller) ResetQueue(controller) ReadableByteStreamControllerClearAlgorithms(controller) ReadableStreamError(stream, e) } function ReadableByteStreamControllerGetBYOBRequest(controller) { if ( controller._byobRequest === null && controller._pendingPullIntos.length > 0 ) { const firstDescriptor = controller._pendingPullIntos.peek() const view = new Uint8Array( firstDescriptor.buffer, firstDescriptor.byteOffset + firstDescriptor.bytesFilled, firstDescriptor.byteLength - firstDescriptor.bytesFilled ) const byobRequest = Object.create(ReadableStreamBYOBRequest.prototype) SetUpReadableStreamBYOBRequest(byobRequest, controller, view) controller._byobRequest = byobRequest } return controller._byobRequest } function ReadableByteStreamControllerGetDesiredSize(controller) { const state = controller._controlledReadableByteStream._state if (state === 'errored') { return null } if (state === 'closed') { return 0 } return controller._strategyHWM - controller._queueTotalSize } function ReadableByteStreamControllerRespond(controller, bytesWritten) { const firstDescriptor = controller._pendingPullIntos.peek() const state = controller._controlledReadableByteStream._state if (state === 'closed') { if (bytesWritten !== 0) { throw new TypeError( 'bytesWritten must be 0 when calling respond() on a closed stream' ) } } else { if (bytesWritten === 0) { throw new TypeError( 'bytesWritten must be greater than 0 when calling respond() on a readable stream' ) } if ( firstDescriptor.bytesFilled + bytesWritten > firstDescriptor.byteLength ) { throw new RangeError('bytesWritten out of range') } } firstDescriptor.buffer = TransferArrayBuffer(firstDescriptor.buffer) ReadableByteStreamControllerRespondInternal(controller, bytesWritten) } function ReadableByteStreamControllerRespondWithNewView(controller, view) { const firstDescriptor = controller._pendingPullIntos.peek() const state = controller._controlledReadableByteStream._state if (state === 'closed') { if (view.byteLength !== 0) { throw new TypeError( "The view's length must be 0 when calling respondWithNewView() on a closed stream" ) } } else { if (view.byteLength === 0) { throw new TypeError( "The view's length must be greater than 0 when calling respondWithNewView() on a readable stream" ) } } if ( firstDescriptor.byteOffset + firstDescriptor.bytesFilled !== view.byteOffset ) { throw new RangeError( 'The region specified by view does not match byobRequest' ) } if (firstDescriptor.bufferByteLength !== view.buffer.byteLength) { throw new RangeError( 'The buffer of view has different capacity than byobRequest' ) } if ( firstDescriptor.bytesFilled + view.byteLength > firstDescriptor.byteLength ) { throw new RangeError( 'The region specified by view is larger than byobRequest' ) } const viewByteLength = view.byteLength firstDescriptor.buffer = TransferArrayBuffer(view.buffer) ReadableByteStreamControllerRespondInternal(controller, viewByteLength) } function SetUpReadableByteStreamController( stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, autoAllocateChunkSize ) { controller._controlledReadableByteStream = stream controller._pullAgain = false controller._pulling = false controller._byobRequest = null // Need to set the slots so that the assert doesn't fire. In the spec the slots already exist implicitly. controller._queue = controller._queueTotalSize = undefined ResetQueue(controller) controller._closeRequested = false controller._started = false controller._strategyHWM = highWaterMark controller._pullAlgorithm = pullAlgorithm controller._cancelAlgorithm = cancelAlgorithm controller._autoAllocateChunkSize = autoAllocateChunkSize controller._pendingPullIntos = new SimpleQueue() stream._readableStreamController = controller const startResult = startAlgorithm() uponPromise( promiseResolvedWith(startResult), () => { controller._started = true ReadableByteStreamControllerCallPullIfNeeded(controller) }, (r) => { ReadableByteStreamControllerError(controller, r) } ) } function SetUpReadableByteStreamControllerFromUnderlyingSource( stream, underlyingByteSource, highWaterMark ) { const controller = Object.create(ReadableByteStreamController.prototype) let startAlgorithm = () => undefined let pullAlgorithm = () => promiseResolvedWith(undefined) let cancelAlgorithm = () => promiseResolvedWith(undefined) if (underlyingByteSource.start !== undefined) { startAlgorithm = () => underlyingByteSource.start(controller) } if (underlyingByteSource.pull !== undefined) { pullAlgorithm = () => underlyingByteSource.pull(controller) } if (underlyingByteSource.cancel !== undefined) { cancelAlgorithm = (reason) => underlyingByteSource.cancel(reason) } const autoAllocateChunkSize = underlyingByteSource.autoAllocateChunkSize if (autoAllocateChunkSize === 0) { throw new TypeError('autoAllocateChunkSize must be greater than 0') } SetUpReadableByteStreamController( stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, autoAllocateChunkSize ) } function SetUpReadableStreamBYOBRequest(request, controller, view) { request._associatedReadableByteStreamController = controller request._view = view } // Helper functions for the ReadableStreamBYOBRequest. function byobRequestBrandCheckException(name) { return new TypeError( `ReadableStreamBYOBRequest.prototype.${name} can only be used on a ReadableStreamBYOBRequest` ) } // Helper functions for the ReadableByteStreamController. function byteStreamControllerBrandCheckException(name) { return new TypeError( `ReadableByteStreamController.prototype.${name} can only be used on a ReadableByteStreamController` ) } // Abstract operations for the ReadableStream. function AcquireReadableStreamBYOBReader(stream) { return new ReadableStreamBYOBReader(stream) } // ReadableStream API exposed for controllers. function ReadableStreamAddReadIntoRequest(stream, readIntoRequest) { stream._reader._readIntoRequests.push(readIntoRequest) } function ReadableStreamFulfillReadIntoRequest(stream, chunk, done) { const reader = stream._reader const readIntoRequest = reader._readIntoRequests.shift() if (done) { readIntoRequest._closeSteps(chunk) } else { readIntoRequest._chunkSteps(chunk) } } function ReadableStreamGetNumReadIntoRequests(stream) { return stream._reader._readIntoRequests.length } function ReadableStreamHasBYOBReader(stream) { const reader = stream._reader if (reader === undefined) { return false } if (!IsReadableStreamBYOBReader(reader)) { return false } return true } /** * A BYOB reader vended by a {@link ReadableStream}. * * @public */ class ReadableStreamBYOBReader { constructor(stream) { assertRequiredArgument(stream, 1, 'ReadableStreamBYOBReader') assertReadableStream(stream, 'First parameter') if (IsReadableStreamLocked(stream)) { throw new TypeError( 'This stream has already been locked for exclusive reading by another reader' ) } if (!IsReadableByteStreamController(stream._readableStreamController)) { throw new TypeError( 'Cannot construct a ReadableStreamBYOBReader for a stream not constructed with a byte ' + 'source' ) } ReadableStreamReaderGenericInitialize(this, stream) this._readIntoRequests = new SimpleQueue() } /** * Returns a promise that will be fulfilled when the stream becomes closed, or rejected if the stream ever errors or * the reader's lock is released before the stream finishes closing. */ get closed() { if (!IsReadableStreamBYOBReader(this)) { return promiseRejectedWith(byobReaderBrandCheckException('closed')) } return this._closedPromise } /** * If the reader is active, behaves the same as {@link ReadableStream.cancel | stream.cancel(reason)}. */ cancel(reason = undefined) { if (!IsReadableStreamBYOBReader(this)) { return promiseRejectedWith(byobReaderBrandCheckException('cancel')) } if (this._ownerReadableStream === undefined) { return promiseRejectedWith(readerLockException('cancel')) } return ReadableStreamReaderGenericCancel(this, reason) } /** * Attempts to reads bytes into view, and returns a promise resolved with the result. * * If reading a chunk causes the queue to become empty, more data will be pulled from the underlying source. */ read(view) { if (!IsReadableStreamBYOBReader(this)) { return promiseRejectedWith(byobReaderBrandCheckException('read')) } if (!ArrayBuffer.isView(view)) { return promiseRejectedWith( new TypeError('view must be an array buffer view') ) } if (view.byteLength === 0) { return promiseRejectedWith( new TypeError('view must have non-zero byteLength') ) } if (view.buffer.byteLength === 0) { return promiseRejectedWith( new TypeError(`view's buffer must have non-zero byteLength`) ) } if (IsDetachedBuffer(view.buffer)); if (this._ownerReadableStream === undefined) { return promiseRejectedWith(readerLockException('read from')) } let resolvePromise let rejectPromise const promise = newPromise((resolve, reject) => { resolvePromise = resolve rejectPromise = reject }) const readIntoRequest = { _chunkSteps: (chunk) => resolvePromise({ value: chunk, done: false }), _closeSteps: (chunk) => resolvePromise({ value: chunk, done: true }), _errorSteps: (e) => rejectPromise(e), } ReadableStreamBYOBReaderRead(this, view, readIntoRequest) return promise } /** * Releases the reader's lock on the corresponding stream. After the lock is released, the reader is no longer active. * If the associated stream is errored when the lock is released, the reader will appear errored in the same way * from now on; otherwise, the reader will appear closed. * * A reader's lock cannot be released while it still has a pending read request, i.e., if a promise returned by * the reader's {@link ReadableStreamBYOBReader.read | read()} method has not yet been settled. Attempting to * do so will throw a `TypeError` and leave the reader locked to the stream. */ releaseLock() { if (!IsReadableStreamBYOBReader(this)) { throw byobReaderBrandCheckException('releaseLock') } if (this._ownerReadableStream === undefined) { return } if (this._readIntoRequests.length > 0) { throw new TypeError( 'Tried to release a reader lock when that reader has pending read() calls un-settled' ) } ReadableStreamReaderGenericRelease(this) } } Object.defineProperties(ReadableStreamBYOBReader.prototype, { cancel: { enumerable: true }, read: { enumerable: true }, releaseLock: { enumerable: true }, closed: { enumerable: true }, }) // Abstract operations for the readers. function IsReadableStreamBYOBReader(x) { if (!typeIsObject(x)) { return false } if (!Object.prototype.hasOwnProperty.call(x, '_readIntoRequests')) { return false } return x instanceof ReadableStreamBYOBReader } function ReadableStreamBYOBReaderRead(reader, view, readIntoRequest) { const stream = reader._ownerReadableStream stream._disturbed = true if (stream._state === 'errored') { readIntoRequest._errorSteps(stream._storedError) } else { ReadableByteStreamControllerPullInto( stream._readableStreamController, view, readIntoRequest ) } } // Helper functions for the ReadableStreamBYOBReader. function byobReaderBrandCheckException(name) { return new TypeError( `ReadableStreamBYOBReader.prototype.${name} can only be used on a ReadableStreamBYOBReader` ) } function ExtractHighWaterMark(strategy, defaultHWM) { const { highWaterMark } = strategy if (highWaterMark === undefined) { return defaultHWM } if (NumberIsNaN(highWaterMark) || highWaterMark < 0) { throw new RangeError('Invalid highWaterMark') } return highWaterMark } function ExtractSizeAlgorithm(strategy) { const { size } = strategy if (!size) { return () => 1 } return size } function convertQueuingStrategy(init, context) { assertDictionary(init, context) const highWaterMark = init === null || init === void 0 ? void 0 : init.highWaterMark const size = init === null || init === void 0 ? void 0 : init.size return { highWaterMark: highWaterMark === undefined ? undefined : convertUnrestrictedDouble(highWaterMark), size: size === undefined ? undefined : convertQueuingStrategySize(size, `${context} has member 'size' that`), } } function convertQueuingStrategySize(fn, context) { assertFunction(fn, context) return (chunk) => convertUnrestrictedDouble(fn(chunk)) } function convertUnderlyingSink(original, context) { assertDictionary(original, context) const abort = original === null || original === void 0 ? void 0 : original.abort const close = original === null || original === void 0 ? void 0 : original.close const start = original === null || original === void 0 ? void 0 : original.start const type = original === null || original === void 0 ? void 0 : original.type const write = original === null || original === void 0 ? void 0 : original.write return { abort: abort === undefined ? undefined : convertUnderlyingSinkAbortCallback( abort, original, `${context} has member 'abort' that` ), close: close === undefined ? undefined : convertUnderlyingSinkCloseCallback( close, original, `${context} has member 'close' that` ), start: start === undefined ? undefined : convertUnderlyingSinkStartCallback( start, original, `${context} has member 'start' that` ), write: write === undefined ? undefined : convertUnderlyingSinkWriteCallback( write, original, `${context} has member 'write' that` ), type, } } function convertUnderlyingSinkAbortCallback(fn, original, context) { assertFunction(fn, context) return (reason) => promiseCall(fn, original, [reason]) } function convertUnderlyingSinkCloseCallback(fn, original, context) { assertFunction(fn, context) return () => promiseCall(fn, original, []) } function convertUnderlyingSinkStartCallback(fn, original, context) { assertFunction(fn, context) return (controller) => reflectCall(fn, original, [controller]) } function convertUnderlyingSinkWriteCallback(fn, original, context) { assertFunction(fn, context) return (chunk, controller) => promiseCall(fn, original, [chunk, controller]) } function assertWritableStream(x, context) { if (!IsWritableStream(x)) { throw new TypeError(`${context} is not a WritableStream.`) } } function isAbortSignal$1(value) { if (typeof value !== 'object' || value === null) { return false } try { return typeof value.aborted === 'boolean' } catch (_a) { // AbortSignal.prototype.aborted throws if its brand check fails return false } } /** * A writable stream represents a destination for data, into which you can write. * * @public */ class WritableStream { constructor(rawUnderlyingSink = {}, rawStrategy = {}) { if (rawUnderlyingSink === undefined) { rawUnderlyingSink = null } else { assertObject(rawUnderlyingSink, 'First parameter') } const strategy = convertQueuingStrategy(rawStrategy, 'Second parameter') const underlyingSink = convertUnderlyingSink( rawUnderlyingSink, 'First parameter' ) InitializeWritableStream(this) const type = underlyingSink.type if (type !== undefined) { throw new RangeError('Invalid type is specified') } const sizeAlgorithm = ExtractSizeAlgorithm(strategy) const highWaterMark = ExtractHighWaterMark(strategy, 1) SetUpWritableStreamDefaultControllerFromUnderlyingSink( this, underlyingSink, highWaterMark, sizeAlgorithm ) } /** * Returns whether or not the writable stream is locked to a writer. */ get locked() { if (!IsWritableStream(this)) { throw streamBrandCheckException$2('locked') } return IsWritableStreamLocked(this) } /** * Aborts the stream, signaling that the producer can no longer successfully write to the stream and it is to be * immediately moved to an errored state, with any queued-up writes discarded. This will also execute any abort * mechanism of the underlying sink. * * The returned promise will fulfill if the stream shuts down successfully, or reject if the underlying sink signaled * that there was an error doing so. Additionally, it will reject with a `TypeError` (without attempting to cancel * the stream) if the stream is currently locked. */ abort(reason = undefined) { if (!IsWritableStream(this)) { return promiseRejectedWith(streamBrandCheckException$2('abort')) } if (IsWritableStreamLocked(this)) { return promiseRejectedWith( new TypeError('Cannot abort a stream that already has a writer') ) } return WritableStreamAbort(this, reason) } /** * Closes the stream. The underlying sink will finish processing any previously-written chunks, before invoking its * close behavior. During this time any further attempts to write will fail (without erroring the stream). * * The method returns a promise that will fulfill if all remaining chunks are successfully written and the stream * successfully closes, or rejects if an error is encountered during this process. Additionally, it will reject with * a `TypeError` (without attempting to cancel the stream) if the stream is currently locked. */ close() { if (!IsWritableStream(this)) { return promiseRejectedWith(streamBrandCheckException$2('close')) } if (IsWritableStreamLocked(this)) { return promiseRejectedWith( new TypeError('Cannot close a stream that already has a writer') ) } if (WritableStreamCloseQueuedOrInFlight(this)) { return promiseRejectedWith( new TypeError('Cannot close an already-closing stream') ) } return WritableStreamClose(this) } /** * Creates a {@link WritableStreamDefaultWriter | writer} and locks the stream to the new writer. While the stream * is locked, no other writer can be acquired until this one is released. * * This functionality is especially useful for creating abstractions that desire the ability to write to a stream * without interruption or interleaving. By getting a writer for the stream, you can ensure nobody else can write at * the same time, which would cause the resulting written data to be unpredictable and probably useless. */ getWriter() { if (!IsWritableStream(this)) { throw streamBrandCheckException$2('getWriter') } return AcquireWritableStreamDefaultWriter(this) } } Object.defineProperties(WritableStream.prototype, { abort: { enumerable: true }, close: { enumerable: true }, getWriter: { enumerable: true }, locked: { enumerable: true }, }) // Abstract operations for the WritableStream. function AcquireWritableStreamDefaultWriter(stream) { return new WritableStreamDefaultWriter(stream) } // Throws if and only if startAlgorithm throws. function CreateWritableStream( startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark = 1, sizeAlgorithm = () => 1 ) { const stream = Object.create(WritableStream.prototype) InitializeWritableStream(stream) const controller = Object.create(WritableStreamDefaultController.prototype) SetUpWritableStreamDefaultController( stream, controller, startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm ) return stream } function InitializeWritableStream(stream) { stream._state = 'writable' // The error that will be reported by new method calls once the state becomes errored. Only set when [[state]] is // 'erroring' or 'errored'. May be set to an undefined value. stream._storedError = undefined stream._writer = undefined // Initialize to undefined first because the constructor of the controller checks this // variable to validate the caller. stream._writableStreamController = undefined // This queue is placed here instead of the writer class in order to allow for passing a writer to the next data // producer without waiting for the queued writes to finish. stream._writeRequests = new SimpleQueue() // Write requests are removed from _writeRequests when write() is called on the underlying sink. This prevents // them from being erroneously rejected on error. If a write() call is in-flight, the request is stored here. stream._inFlightWriteRequest = undefined // The promise that was returned from writer.close(). Stored here because it may be fulfilled after the writer // has been detached. stream._closeRequest = undefined // Close request is removed from _closeRequest when close() is called on the underlying sink. This prevents it // from being erroneously rejected on error. If a close() call is in-flight, the request is stored here. stream._inFlightCloseRequest = undefined // The promise that was returned from writer.abort(). This may also be fulfilled after the writer has detached. stream._pendingAbortRequest = undefined // The backpressure signal set by the controller. stream._backpressure = false } function IsWritableStream(x) { if (!typeIsObject(x)) { return false } if (!Object.prototype.hasOwnProperty.call(x, '_writableStreamController')) { return false } return x instanceof WritableStream } function IsWritableStreamLocked(stream) { if (stream._writer === undefined) { return false } return true } function WritableStreamAbort(stream, reason) { var _a if (stream._state === 'closed' || stream._state === 'errored') { return promiseResolvedWith(undefined) } stream._writableStreamController._abortReason = reason ;(_a = stream._writableStreamController._abortController) === null || _a === void 0 ? void 0 : _a.abort() // TypeScript narrows the type of `stream._state` down to 'writable' | 'erroring', // but it doesn't know that signaling abort runs author code that might have changed the state. // Widen the type again by casting to WritableStreamState. const state = stream._state if (state === 'closed' || state === 'errored') { return promiseResolvedWith(undefined) } if (stream._pendingAbortRequest !== undefined) { return stream._pendingAbortRequest._promise } let wasAlreadyErroring = false if (state === 'erroring') { wasAlreadyErroring = true // reason will not be used, so don't keep a reference to it. reason = undefined } const promise = newPromise((resolve, reject) => { stream._pendingAbortRequest = { _promise: undefined, _resolve: resolve, _reject: reject, _reason: reason, _wasAlreadyErroring: wasAlreadyErroring, } }) stream._pendingAbortRequest._promise = promise if (!wasAlreadyErroring) { WritableStreamStartErroring(stream, reason) } return promise } function WritableStreamClose(stream) { const state = stream._state if (state === 'closed' || state === 'errored') { return promiseRejectedWith( new TypeError( `The stream (in ${state} state) is not in the writable state and cannot be closed` ) ) } const promise = newPromise((resolve, reject) => { const closeRequest = { _resolve: resolve, _reject: reject, } stream._closeRequest = closeRequest }) const writer = stream._writer if (writer !== undefined && stream._backpressure && state === 'writable') { defaultWriterReadyPromiseResolve(writer) } WritableStreamDefaultControllerClose(stream._writableStreamController) return promise } // WritableStream API exposed for controllers. function WritableStreamAddWriteRequest(stream) { const promise = newPromise((resolve, reject) => { const writeRequest = { _resolve: resolve, _reject: reject, } stream._writeRequests.push(writeRequest) }) return promise } function WritableStreamDealWithRejection(stream, error) { const state = stream._state if (state === 'writable') { WritableStreamStartErroring(stream, error) return } WritableStreamFinishErroring(stream) } function WritableStreamStartErroring(stream, reason) { const controller = stream._writableStreamController stream._state = 'erroring' stream._storedError = reason const writer = stream._writer if (writer !== undefined) { WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, reason) } if ( !WritableStreamHasOperationMarkedInFlight(stream) && controller._started ) { WritableStreamFinishErroring(stream) } } function WritableStreamFinishErroring(stream) { stream._state = 'errored' stream._writableStreamController[ErrorSteps]() const storedError = stream._storedError stream._writeRequests.forEach((writeRequest) => { writeRequest._reject(storedError) }) stream._writeRequests = new SimpleQueue() if (stream._pendingAbortRequest === undefined) { WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream) return } const abortRequest = stream._pendingAbortRequest stream._pendingAbortRequest = undefined if (abortRequest._wasAlreadyErroring) { abortRequest._reject(storedError) WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream) return } const promise = stream._writableStreamController[AbortSteps]( abortRequest._reason ) uponPromise( promise, () => { abortRequest._resolve() WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream) }, (reason) => { abortRequest._reject(reason) WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream) } ) } function WritableStreamFinishInFlightWrite(stream) { stream._inFlightWriteRequest._resolve(undefined) stream._inFlightWriteRequest = undefined } function WritableStreamFinishInFlightWriteWithError(stream, error) { stream._inFlightWriteRequest._reject(error) stream._inFlightWriteRequest = undefined WritableStreamDealWithRejection(stream, error) } function WritableStreamFinishInFlightClose(stream) { stream._inFlightCloseRequest._resolve(undefined) stream._inFlightCloseRequest = undefined const state = stream._state if (state === 'erroring') { // The error was too late to do anything, so it is ignored. stream._storedError = undefined if (stream._pendingAbortRequest !== undefined) { stream._pendingAbortRequest._resolve() stream._pendingAbortRequest = undefined } } stream._state = 'closed' const writer = stream._writer if (writer !== undefined) { defaultWriterClosedPromiseResolve(writer) } } function WritableStreamFinishInFlightCloseWithError(stream, error) { stream._inFlightCloseRequest._reject(error) stream._inFlightCloseRequest = undefined // Never execute sink abort() after sink close(). if (stream._pendingAbortRequest !== undefined) { stream._pendingAbortRequest._reject(error) stream._pendingAbortRequest = undefined } WritableStreamDealWithRejection(stream, error) } // TODO(ricea): Fix alphabetical order. function WritableStreamCloseQueuedOrInFlight(stream) { if ( stream._closeRequest === undefined && stream._inFlightCloseRequest === undefined ) { return false } return true } function WritableStreamHasOperationMarkedInFlight(stream) { if ( stream._inFlightWriteRequest === undefined && stream._inFlightCloseRequest === undefined ) { return false } return true } function WritableStreamMarkCloseRequestInFlight(stream) { stream._inFlightCloseRequest = stream._closeRequest stream._closeRequest = undefined } function WritableStreamMarkFirstWriteRequestInFlight(stream) { stream._inFlightWriteRequest = stream._writeRequests.shift() } function WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream) { if (stream._closeRequest !== undefined) { stream._closeRequest._reject(stream._storedError) stream._closeRequest = undefined } const writer = stream._writer if (writer !== undefined) { defaultWriterClosedPromiseReject(writer, stream._storedError) } } function WritableStreamUpdateBackpressure(stream, backpressure) { const writer = stream._writer if (writer !== undefined && backpressure !== stream._backpressure) { if (backpressure) { defaultWriterReadyPromiseReset(writer) } else { defaultWriterReadyPromiseResolve(writer) } } stream._backpressure = backpressure } /** * A default writer vended by a {@link WritableStream}. * * @public */ class WritableStreamDefaultWriter { constructor(stream) { assertRequiredArgument(stream, 1, 'WritableStreamDefaultWriter') assertWritableStream(stream, 'First parameter') if (IsWritableStreamLocked(stream)) { throw new TypeError( 'This stream has already been locked for exclusive writing by another writer' ) } this._ownerWritableStream = stream stream._writer = this const state = stream._state if (state === 'writable') { if ( !WritableStreamCloseQueuedOrInFlight(stream) && stream._backpressure ) { defaultWriterReadyPromiseInitialize(this) } else { defaultWriterReadyPromiseInitializeAsResolved(this) } defaultWriterClosedPromiseInitialize(this) } else if (state === 'erroring') { defaultWriterReadyPromiseInitializeAsRejected(this, stream._storedError) defaultWriterClosedPromiseInitialize(this) } else if (state === 'closed') { defaultWriterReadyPromiseInitializeAsResolved(this) defaultWriterClosedPromiseInitializeAsResolved(this) } else { const storedError = stream._storedError defaultWriterReadyPromiseInitializeAsRejected(this, storedError) defaultWriterClosedPromiseInitializeAsRejected(this, storedError) } } /** * Returns a promise that will be fulfilled when the stream becomes closed, or rejected if the stream ever errors or * the writer’s lock is released before the stream finishes closing. */ get closed() { if (!IsWritableStreamDefaultWriter(this)) { return promiseRejectedWith(defaultWriterBrandCheckException('closed')) } return this._closedPromise } /** * Returns the desired size to fill the stream’s internal queue. It can be negative, if the queue is over-full. * A producer can use this information to determine the right amount of data to write. * * It will be `null` if the stream cannot be successfully written to (due to either being errored, or having an abort * queued up). It will return zero if the stream is closed. And the getter will throw an exception if invoked when * the writer’s lock is released. */ get desiredSize() { if (!IsWritableStreamDefaultWriter(this)) { throw defaultWriterBrandCheckException('desiredSize') } if (this._ownerWritableStream === undefined) { throw defaultWriterLockException('desiredSize') } return WritableStreamDefaultWriterGetDesiredSize(this) } /** * Returns a promise that will be fulfilled when the desired size to fill the stream’s internal queue transitions * from non-positive to positive, signaling that it is no longer applying backpressure. Once the desired size dips * back to zero or below, the getter will return a new promise that stays pending until the next transition. * * If the stream becomes errored or aborted, or the writer’s lock is released, the returned promise will become * rejected. */ get ready() { if (!IsWritableStreamDefaultWriter(this)) { return promiseRejectedWith(defaultWriterBrandCheckException('ready')) } return this._readyPromise } /** * If the reader is active, behaves the same as {@link WritableStream.abort | stream.abort(reason)}. */ abort(reason = undefined) { if (!IsWritableStreamDefaultWriter(this)) { return promiseRejectedWith(defaultWriterBrandCheckException('abort')) } if (this._ownerWritableStream === undefined) { return promiseRejectedWith(defaultWriterLockException('abort')) } return WritableStreamDefaultWriterAbort(this, reason) } /** * If the reader is active, behaves the same as {@link WritableStream.close | stream.close()}. */ close() { if (!IsWritableStreamDefaultWriter(this)) { return promiseRejectedWith(defaultWriterBrandCheckException('close')) } const stream = this._ownerWritableStream if (stream === undefined) { return promiseRejectedWith(defaultWriterLockException('close')) } if (WritableStreamCloseQueuedOrInFlight(stream)) { return promiseRejectedWith( new TypeError('Cannot close an already-closing stream') ) } return WritableStreamDefaultWriterClose(this) } /** * Releases the writer’s lock on the corresponding stream. After the lock is released, the writer is no longer active. * If the associated stream is errored when the lock is released, the writer will appear errored in the same way from * now on; otherwise, the writer will appear closed. * * Note that the lock can still be released even if some ongoing writes have not yet finished (i.e. even if the * promises returned from previous calls to {@link WritableStreamDefaultWriter.write | write()} have not yet settled). * It’s not necessary to hold the lock on the writer for the duration of the write; the lock instead simply prevents * other producers from writing in an interleaved manner. */ releaseLock() { if (!IsWritableStreamDefaultWriter(this)) { throw defaultWriterBrandCheckException('releaseLock') } const stream = this._ownerWritableStream if (stream === undefined) { return } WritableStreamDefaultWriterRelease(this) } write(chunk = undefined) { if (!IsWritableStreamDefaultWriter(this)) { return promiseRejectedWith(defaultWriterBrandCheckException('write')) } if (this._ownerWritableStream === undefined) { return promiseRejectedWith(defaultWriterLockException('write to')) } return WritableStreamDefaultWriterWrite(this, chunk) } } Object.defineProperties(WritableStreamDefaultWriter.prototype, { abort: { enumerable: true }, close: { enumerable: true }, releaseLock: { enumerable: true }, write: { enumerable: true }, closed: { enumerable: true }, desiredSize: { enumerable: true }, ready: { enumerable: true }, }) // Abstract operations for the WritableStreamDefaultWriter. function IsWritableStreamDefaultWriter(x) { if (!typeIsObject(x)) { return false } if (!Object.prototype.hasOwnProperty.call(x, '_ownerWritableStream')) { return false } return x instanceof WritableStreamDefaultWriter } // A client of WritableStreamDefaultWriter may use these functions directly to bypass state check. function WritableStreamDefaultWriterAbort(writer, reason) { const stream = writer._ownerWritableStream return WritableStreamAbort(stream, reason) } function WritableStreamDefaultWriterClose(writer) { const stream = writer._ownerWritableStream return WritableStreamClose(stream) } function WritableStreamDefaultWriterCloseWithErrorPropagation(writer) { const stream = writer._ownerWritableStream const state = stream._state if (WritableStreamCloseQueuedOrInFlight(stream) || state === 'closed') { return promiseResolvedWith(undefined) } if (state === 'errored') { return promiseRejectedWith(stream._storedError) } return WritableStreamDefaultWriterClose(writer) } function WritableStreamDefaultWriterEnsureClosedPromiseRejected(writer, error) { if (writer._closedPromiseState === 'pending') { defaultWriterClosedPromiseReject(writer, error) } else { defaultWriterClosedPromiseResetToRejected(writer, error) } } function WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, error) { if (writer._readyPromiseState === 'pending') { defaultWriterReadyPromiseReject(writer, error) } else { defaultWriterReadyPromiseResetToRejected(writer, error) } } function WritableStreamDefaultWriterGetDesiredSize(writer) { const stream = writer._ownerWritableStream const state = stream._state if (state === 'errored' || state === 'erroring') { return null } if (state === 'closed') { return 0 } return WritableStreamDefaultControllerGetDesiredSize( stream._writableStreamController ) } function WritableStreamDefaultWriterRelease(writer) { const stream = writer._ownerWritableStream const releasedError = new TypeError( `Writer was released and can no longer be used to monitor the stream's closedness` ) WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, releasedError) // The state transitions to "errored" before the sink abort() method runs, but the writer.closed promise is not // rejected until afterwards. This means that simply testing state will not work. WritableStreamDefaultWriterEnsureClosedPromiseRejected(writer, releasedError) stream._writer = undefined writer._ownerWritableStream = undefined } function WritableStreamDefaultWriterWrite(writer, chunk) { const stream = writer._ownerWritableStream const controller = stream._writableStreamController const chunkSize = WritableStreamDefaultControllerGetChunkSize( controller, chunk ) if (stream !== writer._ownerWritableStream) { return promiseRejectedWith(defaultWriterLockException('write to')) } const state = stream._state if (state === 'errored') { return promiseRejectedWith(stream._storedError) } if (WritableStreamCloseQueuedOrInFlight(stream) || state === 'closed') { return promiseRejectedWith( new TypeError('The stream is closing or closed and cannot be written to') ) } if (state === 'erroring') { return promiseRejectedWith(stream._storedError) } const promise = WritableStreamAddWriteRequest(stream) WritableStreamDefaultControllerWrite(controller, chunk, chunkSize) return promise } const closeSentinel = {} /** * Allows control of a {@link WritableStream | writable stream}'s state and internal queue. * * @public */ class WritableStreamDefaultController { constructor() { throw new TypeError('Illegal constructor') } /** * The reason which was passed to `WritableStream.abort(reason)` when the stream was aborted. * * @deprecated * This property has been removed from the specification, see https://github.com/whatwg/streams/pull/1177. * Use {@link WritableStreamDefaultController.signal}'s `reason` instead. */ get abortReason() { if (!IsWritableStreamDefaultController(this)) { throw defaultControllerBrandCheckException$2('abortReason') } return this._abortReason } /** * An `AbortSignal` that can be used to abort the pending write or close operation when the stream is aborted. */ get signal() { if (!IsWritableStreamDefaultController(this)) { throw defaultControllerBrandCheckException$2('signal') } if (this._abortController === undefined) { // Older browsers or older Node versions may not support `AbortController` or `AbortSignal`. // We don't want to bundle and ship an `AbortController` polyfill together with our polyfill, // so instead we only implement support for `signal` if we find a global `AbortController` constructor. throw new TypeError( 'WritableStreamDefaultController.prototype.signal is not supported' ) } return this._abortController.signal } /** * Closes the controlled writable stream, making all future interactions with it fail with the given error `e`. * * This method is rarely used, since usually it suffices to return a rejected promise from one of the underlying * sink's methods. However, it can be useful for suddenly shutting down a stream in response to an event outside the * normal lifecycle of interactions with the underlying sink. */ error(e = undefined) { if (!IsWritableStreamDefaultController(this)) { throw defaultControllerBrandCheckException$2('error') } const state = this._controlledWritableStream._state if (state !== 'writable') { // The stream is closed, errored or will be soon. The sink can't do anything useful if it gets an error here, so // just treat it as a no-op. return } WritableStreamDefaultControllerError(this, e) } /** @internal */ [AbortSteps](reason) { const result = this._abortAlgorithm(reason) WritableStreamDefaultControllerClearAlgorithms(this) return result } /** @internal */ [ErrorSteps]() { ResetQueue(this) } } Object.defineProperties(WritableStreamDefaultController.prototype, { abortReason: { enumerable: true }, signal: { enumerable: true }, error: { enumerable: true }, }) // Abstract operations implementing interface required by the WritableStream. function IsWritableStreamDefaultController(x) { if (!typeIsObject(x)) { return false } if (!Object.prototype.hasOwnProperty.call(x, '_controlledWritableStream')) { return false } return x instanceof WritableStreamDefaultController } function SetUpWritableStreamDefaultController( stream, controller, startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm ) { controller._controlledWritableStream = stream stream._writableStreamController = controller // Need to set the slots so that the assert doesn't fire. In the spec the slots already exist implicitly. controller._queue = undefined controller._queueTotalSize = undefined ResetQueue(controller) controller._abortReason = undefined controller._abortController = new AbortController() controller._started = false controller._strategySizeAlgorithm = sizeAlgorithm controller._strategyHWM = highWaterMark controller._writeAlgorithm = writeAlgorithm controller._closeAlgorithm = closeAlgorithm controller._abortAlgorithm = abortAlgorithm const backpressure = WritableStreamDefaultControllerGetBackpressure(controller) WritableStreamUpdateBackpressure(stream, backpressure) const startResult = startAlgorithm() const startPromise = promiseResolvedWith(startResult) uponPromise( startPromise, () => { controller._started = true WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller) }, (r) => { controller._started = true WritableStreamDealWithRejection(stream, r) } ) } function SetUpWritableStreamDefaultControllerFromUnderlyingSink( stream, underlyingSink, highWaterMark, sizeAlgorithm ) { const controller = Object.create(WritableStreamDefaultController.prototype) let startAlgorithm = () => undefined let writeAlgorithm = () => promiseResolvedWith(undefined) let closeAlgorithm = () => promiseResolvedWith(undefined) let abortAlgorithm = () => promiseResolvedWith(undefined) if (underlyingSink.start !== undefined) { startAlgorithm = () => underlyingSink.start(controller) } if (underlyingSink.write !== undefined) { writeAlgorithm = (chunk) => underlyingSink.write(chunk, controller) } if (underlyingSink.close !== undefined) { closeAlgorithm = () => underlyingSink.close() } if (underlyingSink.abort !== undefined) { abortAlgorithm = (reason) => underlyingSink.abort(reason) } SetUpWritableStreamDefaultController( stream, controller, startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm ) } // ClearAlgorithms may be called twice. Erroring the same stream in multiple ways will often result in redundant calls. function WritableStreamDefaultControllerClearAlgorithms(controller) { controller._writeAlgorithm = undefined controller._closeAlgorithm = undefined controller._abortAlgorithm = undefined controller._strategySizeAlgorithm = undefined } function WritableStreamDefaultControllerClose(controller) { EnqueueValueWithSize(controller, closeSentinel, 0) WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller) } function WritableStreamDefaultControllerGetChunkSize(controller, chunk) { try { return controller._strategySizeAlgorithm(chunk) } catch (chunkSizeE) { WritableStreamDefaultControllerErrorIfNeeded(controller, chunkSizeE) return 1 } } function WritableStreamDefaultControllerGetDesiredSize(controller) { return controller._strategyHWM - controller._queueTotalSize } function WritableStreamDefaultControllerWrite(controller, chunk, chunkSize) { try { EnqueueValueWithSize(controller, chunk, chunkSize) } catch (enqueueE) { WritableStreamDefaultControllerErrorIfNeeded(controller, enqueueE) return } const stream = controller._controlledWritableStream if ( !WritableStreamCloseQueuedOrInFlight(stream) && stream._state === 'writable' ) { const backpressure = WritableStreamDefaultControllerGetBackpressure(controller) WritableStreamUpdateBackpressure(stream, backpressure) } WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller) } // Abstract operations for the WritableStreamDefaultController. function WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller) { const stream = controller._controlledWritableStream if (!controller._started) { return } if (stream._inFlightWriteRequest !== undefined) { return } const state = stream._state if (state === 'erroring') { WritableStreamFinishErroring(stream) return } if (controller._queue.length === 0) { return } const value = PeekQueueValue(controller) if (value === closeSentinel) { WritableStreamDefaultControllerProcessClose(controller) } else { WritableStreamDefaultControllerProcessWrite(controller, value) } } function WritableStreamDefaultControllerErrorIfNeeded(controller, error) { if (controller._controlledWritableStream._state === 'writable') { WritableStreamDefaultControllerError(controller, error) } } function WritableStreamDefaultControllerProcessClose(controller) { const stream = controller._controlledWritableStream WritableStreamMarkCloseRequestInFlight(stream) DequeueValue(controller) const sinkClosePromise = controller._closeAlgorithm() WritableStreamDefaultControllerClearAlgorithms(controller) uponPromise( sinkClosePromise, () => { WritableStreamFinishInFlightClose(stream) }, (reason) => { WritableStreamFinishInFlightCloseWithError(stream, reason) } ) } function WritableStreamDefaultControllerProcessWrite(controller, chunk) { const stream = controller._controlledWritableStream WritableStreamMarkFirstWriteRequestInFlight(stream) const sinkWritePromise = controller._writeAlgorithm(chunk) uponPromise( sinkWritePromise, () => { WritableStreamFinishInFlightWrite(stream) const state = stream._state DequeueValue(controller) if ( !WritableStreamCloseQueuedOrInFlight(stream) && state === 'writable' ) { const backpressure = WritableStreamDefaultControllerGetBackpressure(controller) WritableStreamUpdateBackpressure(stream, backpressure) } WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller) }, (reason) => { if (stream._state === 'writable') { WritableStreamDefaultControllerClearAlgorithms(controller) } WritableStreamFinishInFlightWriteWithError(stream, reason) } ) } function WritableStreamDefaultControllerGetBackpressure(controller) { const desiredSize = WritableStreamDefaultControllerGetDesiredSize(controller) return desiredSize <= 0 } // A client of WritableStreamDefaultController may use these functions directly to bypass state check. function WritableStreamDefaultControllerError(controller, error) { const stream = controller._controlledWritableStream WritableStreamDefaultControllerClearAlgorithms(controller) WritableStreamStartErroring(stream, error) } // Helper functions for the WritableStream. function streamBrandCheckException$2(name) { return new TypeError( `WritableStream.prototype.${name} can only be used on a WritableStream` ) } // Helper functions for the WritableStreamDefaultController. function defaultControllerBrandCheckException$2(name) { return new TypeError( `WritableStreamDefaultController.prototype.${name} can only be used on a WritableStreamDefaultController` ) } // Helper functions for the WritableStreamDefaultWriter. function defaultWriterBrandCheckException(name) { return new TypeError( `WritableStreamDefaultWriter.prototype.${name} can only be used on a WritableStreamDefaultWriter` ) } function defaultWriterLockException(name) { return new TypeError('Cannot ' + name + ' a stream using a released writer') } function defaultWriterClosedPromiseInitialize(writer) { writer._closedPromise = newPromise((resolve, reject) => { writer._closedPromise_resolve = resolve writer._closedPromise_reject = reject writer._closedPromiseState = 'pending' }) } function defaultWriterClosedPromiseInitializeAsRejected(writer, reason) { defaultWriterClosedPromiseInitialize(writer) defaultWriterClosedPromiseReject(writer, reason) } function defaultWriterClosedPromiseInitializeAsResolved(writer) { defaultWriterClosedPromiseInitialize(writer) defaultWriterClosedPromiseResolve(writer) } function defaultWriterClosedPromiseReject(writer, reason) { if (writer._closedPromise_reject === undefined) { return } setPromiseIsHandledToTrue(writer._closedPromise) writer._closedPromise_reject(reason) writer._closedPromise_resolve = undefined writer._closedPromise_reject = undefined writer._closedPromiseState = 'rejected' } function defaultWriterClosedPromiseResetToRejected(writer, reason) { defaultWriterClosedPromiseInitializeAsRejected(writer, reason) } function defaultWriterClosedPromiseResolve(writer) { if (writer._closedPromise_resolve === undefined) { return } writer._closedPromise_resolve(undefined) writer._closedPromise_resolve = undefined writer._closedPromise_reject = undefined writer._closedPromiseState = 'resolved' } function defaultWriterReadyPromiseInitialize(writer) { writer._readyPromise = newPromise((resolve, reject) => { writer._readyPromise_resolve = resolve writer._readyPromise_reject = reject }) writer._readyPromiseState = 'pending' } function defaultWriterReadyPromiseInitializeAsRejected(writer, reason) { defaultWriterReadyPromiseInitialize(writer) defaultWriterReadyPromiseReject(writer, reason) } function defaultWriterReadyPromiseInitializeAsResolved(writer) { defaultWriterReadyPromiseInitialize(writer) defaultWriterReadyPromiseResolve(writer) } function defaultWriterReadyPromiseReject(writer, reason) { if (writer._readyPromise_reject === undefined) { return } setPromiseIsHandledToTrue(writer._readyPromise) writer._readyPromise_reject(reason) writer._readyPromise_resolve = undefined writer._readyPromise_reject = undefined writer._readyPromiseState = 'rejected' } function defaultWriterReadyPromiseReset(writer) { defaultWriterReadyPromiseInitialize(writer) } function defaultWriterReadyPromiseResetToRejected(writer, reason) { defaultWriterReadyPromiseInitializeAsRejected(writer, reason) } function defaultWriterReadyPromiseResolve(writer) { if (writer._readyPromise_resolve === undefined) { return } writer._readyPromise_resolve(undefined) writer._readyPromise_resolve = undefined writer._readyPromise_reject = undefined writer._readyPromiseState = 'fulfilled' } // eslint-disable-next-line no-redeclarelet DOMException$1=DOMException function ReadableStreamPipeTo( source, dest, preventClose, preventAbort, preventCancel, signal ) { const reader = AcquireReadableStreamDefaultReader(source) const writer = AcquireWritableStreamDefaultWriter(dest) source._disturbed = true let shuttingDown = false // This is used to keep track of the spec's requirement that we wait for ongoing writes during shutdown. let currentWrite = promiseResolvedWith(undefined) return newPromise((resolve, reject) => { let abortAlgorithm if (signal !== undefined) { abortAlgorithm = () => { const error = new DOMException('Aborted', 'AbortError') const actions = [] if (!preventAbort) { actions.push(() => { if (dest._state === 'writable') { return WritableStreamAbort(dest, error) } return promiseResolvedWith(undefined) }) } if (!preventCancel) { actions.push(() => { if (source._state === 'readable') { return ReadableStreamCancel(source, error) } return promiseResolvedWith(undefined) }) } shutdownWithAction( () => Promise.all(actions.map((action) => action())), true, error ) } if (signal.aborted) { abortAlgorithm() return } signal.addEventListener('abort', abortAlgorithm) } // Using reader and writer, read all chunks from this and write them to dest // - Backpressure must be enforced // - Shutdown must stop all activity function pipeLoop() { return newPromise((resolveLoop, rejectLoop) => { function next(done) { if (done) { resolveLoop() } else { // Use `PerformPromiseThen` instead of `uponPromise` to avoid // adding unnecessary `.catch(rethrowAssertionErrorRejection)` handlers PerformPromiseThen(pipeStep(), next, rejectLoop) } } next(false) }) } function pipeStep() { if (shuttingDown) { return promiseResolvedWith(true) } return PerformPromiseThen(writer._readyPromise, () => { return newPromise((resolveRead, rejectRead) => { ReadableStreamDefaultReaderRead(reader, { _chunkSteps: (chunk) => { currentWrite = PerformPromiseThen( WritableStreamDefaultWriterWrite(writer, chunk), undefined, noop$1 ) resolveRead(false) }, _closeSteps: () => resolveRead(true), _errorSteps: rejectRead, }) }) }) } // Errors must be propagated forward isOrBecomesErrored(source, reader._closedPromise, (storedError) => { if (!preventAbort) { shutdownWithAction( () => WritableStreamAbort(dest, storedError), true, storedError ) } else { shutdown(true, storedError) } }) // Errors must be propagated backward isOrBecomesErrored(dest, writer._closedPromise, (storedError) => { if (!preventCancel) { shutdownWithAction( () => ReadableStreamCancel(source, storedError), true, storedError ) } else { shutdown(true, storedError) } }) // Closing must be propagated forward isOrBecomesClosed(source, reader._closedPromise, () => { if (!preventClose) { shutdownWithAction(() => WritableStreamDefaultWriterCloseWithErrorPropagation(writer) ) } else { shutdown() } }) // Closing must be propagated backward if (WritableStreamCloseQueuedOrInFlight(dest) || dest._state === 'closed') { const destClosed = new TypeError( 'the destination writable stream closed before all data could be piped to it' ) if (!preventCancel) { shutdownWithAction( () => ReadableStreamCancel(source, destClosed), true, destClosed ) } else { shutdown(true, destClosed) } } setPromiseIsHandledToTrue(pipeLoop()) function waitForWritesToFinish() { // Another write may have started while we were waiting on this currentWrite, so we have to be sure to wait // for that too. const oldCurrentWrite = currentWrite return PerformPromiseThen(currentWrite, () => oldCurrentWrite !== currentWrite ? waitForWritesToFinish() : undefined ) } function isOrBecomesErrored(stream, promise, action) { if (stream._state === 'errored') { action(stream._storedError) } else { uponRejection(promise, action) } } function isOrBecomesClosed(stream, promise, action) { if (stream._state === 'closed') { action() } else { uponFulfillment(promise, action) } } function shutdownWithAction(action, originalIsError, originalError) { if (shuttingDown) { return } shuttingDown = true if ( dest._state === 'writable' && !WritableStreamCloseQueuedOrInFlight(dest) ) { uponFulfillment(waitForWritesToFinish(), doTheRest) } else { doTheRest() } function doTheRest() { uponPromise( action(), () => finalize(originalIsError, originalError), (newError) => finalize(true, newError) ) } } function shutdown(isError, error) { if (shuttingDown) { return } shuttingDown = true if ( dest._state === 'writable' && !WritableStreamCloseQueuedOrInFlight(dest) ) { uponFulfillment(waitForWritesToFinish(), () => finalize(isError, error)) } else { finalize(isError, error) } } function finalize(isError, error) { WritableStreamDefaultWriterRelease(writer) ReadableStreamReaderGenericRelease(reader) if (signal !== undefined) { signal.removeEventListener('abort', abortAlgorithm) } if (isError) { reject(error) } else { resolve(undefined) } } }) } /** * Allows control of a {@link ReadableStream | readable stream}'s state and internal queue. * * @public */ class ReadableStreamDefaultController { constructor() { throw new TypeError('Illegal constructor') } /** * Returns the desired size to fill the controlled stream's internal queue. It can be negative, if the queue is * over-full. An underlying source ought to use this information to determine when and how to apply backpressure. */ get desiredSize() { if (!IsReadableStreamDefaultController(this)) { throw defaultControllerBrandCheckException$1('desiredSize') } return ReadableStreamDefaultControllerGetDesiredSize(this) } /** * Closes the controlled readable stream. Consumers will still be able to read any previously-enqueued chunks from * the stream, but once those are read, the stream will become closed. */ close() { if (!IsReadableStreamDefaultController(this)) { throw defaultControllerBrandCheckException$1('close') } if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(this)) { throw new TypeError('The stream is not in a state that permits close') } ReadableStreamDefaultControllerClose(this) } enqueue(chunk = undefined) { if (!IsReadableStreamDefaultController(this)) { throw defaultControllerBrandCheckException$1('enqueue') } if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(this)) { throw new TypeError('The stream is not in a state that permits enqueue') } return ReadableStreamDefaultControllerEnqueue(this, chunk) } /** * Errors the controlled readable stream, making all future interactions with it fail with the given error `e`. */ error(e = undefined) { if (!IsReadableStreamDefaultController(this)) { throw defaultControllerBrandCheckException$1('error') } ReadableStreamDefaultControllerError(this, e) } /** @internal */ [CancelSteps](reason) { ResetQueue(this) const result = this._cancelAlgorithm(reason) ReadableStreamDefaultControllerClearAlgorithms(this) return result } /** @internal */ [PullSteps](readRequest) { const stream = this._controlledReadableStream if (this._queue.length > 0) { const chunk = DequeueValue(this) if (this._closeRequested && this._queue.length === 0) { ReadableStreamDefaultControllerClearAlgorithms(this) ReadableStreamClose(stream) } else { ReadableStreamDefaultControllerCallPullIfNeeded(this) } readRequest._chunkSteps(chunk) } else { ReadableStreamAddReadRequest(stream, readRequest) ReadableStreamDefaultControllerCallPullIfNeeded(this) } } } Object.defineProperties(ReadableStreamDefaultController.prototype, { close: { enumerable: true }, enqueue: { enumerable: true }, error: { enumerable: true }, desiredSize: { enumerable: true }, }) // Abstract operations for the ReadableStreamDefaultController. function IsReadableStreamDefaultController(x) { if (!typeIsObject(x)) { return false } if (!Object.prototype.hasOwnProperty.call(x, '_controlledReadableStream')) { return false } return x instanceof ReadableStreamDefaultController } function ReadableStreamDefaultControllerCallPullIfNeeded(controller) { const shouldPull = ReadableStreamDefaultControllerShouldCallPull(controller) if (!shouldPull) { return } if (controller._pulling) { controller._pullAgain = true return } controller._pulling = true const pullPromise = controller._pullAlgorithm() uponPromise( pullPromise, () => { controller._pulling = false if (controller._pullAgain) { controller._pullAgain = false ReadableStreamDefaultControllerCallPullIfNeeded(controller) } }, (e) => { ReadableStreamDefaultControllerError(controller, e) } ) } function ReadableStreamDefaultControllerShouldCallPull(controller) { const stream = controller._controlledReadableStream if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(controller)) { return false } if (!controller._started) { return false } if ( IsReadableStreamLocked(stream) && ReadableStreamGetNumReadRequests(stream) > 0 ) { return true } const desiredSize = ReadableStreamDefaultControllerGetDesiredSize(controller) if (desiredSize > 0) { return true } return false } function ReadableStreamDefaultControllerClearAlgorithms(controller) { controller._pullAlgorithm = undefined controller._cancelAlgorithm = undefined controller._strategySizeAlgorithm = undefined } // A client of ReadableStreamDefaultController may use these functions directly to bypass state check. function ReadableStreamDefaultControllerClose(controller) { if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(controller)) { return } const stream = controller._controlledReadableStream controller._closeRequested = true if (controller._queue.length === 0) { ReadableStreamDefaultControllerClearAlgorithms(controller) ReadableStreamClose(stream) } } function ReadableStreamDefaultControllerEnqueue(controller, chunk) { if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(controller)) { return } const stream = controller._controlledReadableStream if ( IsReadableStreamLocked(stream) && ReadableStreamGetNumReadRequests(stream) > 0 ) { ReadableStreamFulfillReadRequest(stream, chunk, false) } else { let chunkSize try { chunkSize = controller._strategySizeAlgorithm(chunk) } catch (chunkSizeE) { ReadableStreamDefaultControllerError(controller, chunkSizeE) throw chunkSizeE } try { EnqueueValueWithSize(controller, chunk, chunkSize) } catch (enqueueE) { ReadableStreamDefaultControllerError(controller, enqueueE) throw enqueueE } } ReadableStreamDefaultControllerCallPullIfNeeded(controller) } function ReadableStreamDefaultControllerError(controller, e) { const stream = controller._controlledReadableStream if (stream._state !== 'readable') { return } ResetQueue(controller) ReadableStreamDefaultControllerClearAlgorithms(controller) ReadableStreamError(stream, e) } function ReadableStreamDefaultControllerGetDesiredSize(controller) { const state = controller._controlledReadableStream._state if (state === 'errored') { return null } if (state === 'closed') { return 0 } return controller._strategyHWM - controller._queueTotalSize } // This is used in the implementation of TransformStream. function ReadableStreamDefaultControllerHasBackpressure(controller) { if (ReadableStreamDefaultControllerShouldCallPull(controller)) { return false } return true } function ReadableStreamDefaultControllerCanCloseOrEnqueue(controller) { const state = controller._controlledReadableStream._state if (!controller._closeRequested && state === 'readable') { return true } return false } function SetUpReadableStreamDefaultController( stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, sizeAlgorithm ) { controller._controlledReadableStream = stream controller._queue = undefined controller._queueTotalSize = undefined ResetQueue(controller) controller._started = false controller._closeRequested = false controller._pullAgain = false controller._pulling = false controller._strategySizeAlgorithm = sizeAlgorithm controller._strategyHWM = highWaterMark controller._pullAlgorithm = pullAlgorithm controller._cancelAlgorithm = cancelAlgorithm stream._readableStreamController = controller const startResult = startAlgorithm() uponPromise( promiseResolvedWith(startResult), () => { controller._started = true ReadableStreamDefaultControllerCallPullIfNeeded(controller) }, (r) => { ReadableStreamDefaultControllerError(controller, r) } ) } function SetUpReadableStreamDefaultControllerFromUnderlyingSource( stream, underlyingSource, highWaterMark, sizeAlgorithm ) { const controller = Object.create(ReadableStreamDefaultController.prototype) let startAlgorithm = () => undefined let pullAlgorithm = () => promiseResolvedWith(undefined) let cancelAlgorithm = () => promiseResolvedWith(undefined) if (underlyingSource.start !== undefined) { startAlgorithm = () => underlyingSource.start(controller) } if (underlyingSource.pull !== undefined) { pullAlgorithm = () => underlyingSource.pull(controller) } if (underlyingSource.cancel !== undefined) { cancelAlgorithm = (reason) => underlyingSource.cancel(reason) } SetUpReadableStreamDefaultController( stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, sizeAlgorithm ) } // Helper functions for the ReadableStreamDefaultController. function defaultControllerBrandCheckException$1(name) { return new TypeError( `ReadableStreamDefaultController.prototype.${name} can only be used on a ReadableStreamDefaultController` ) } function ReadableStreamTee(stream, cloneForBranch2) { if (IsReadableByteStreamController(stream._readableStreamController)) { return ReadableByteStreamTee(stream) } return ReadableStreamDefaultTee(stream) } function ReadableStreamDefaultTee(stream, cloneForBranch2) { const reader = AcquireReadableStreamDefaultReader(stream) let reading = false let readAgain = false let canceled1 = false let canceled2 = false let reason1 let reason2 let branch1 let branch2 let resolveCancelPromise const cancelPromise = newPromise((resolve) => { resolveCancelPromise = resolve }) function pullAlgorithm() { if (reading) { readAgain = true return promiseResolvedWith(undefined) } reading = true const readRequest = { _chunkSteps: (chunk) => { // This needs to be delayed a microtask because it takes at least a microtask to detect errors (using // reader._closedPromise below), and we want errors in stream to error both branches immediately. We cannot let // successful synchronously-available reads get ahead of asynchronously-available errors. queueMicrotask(() => { readAgain = false const chunk1 = chunk const chunk2 = chunk // There is no way to access the cloning code right now in the reference implementation. // If we add one then we'll need an implementation for serializable objects. // if (!canceled2 && cloneForBranch2) { // chunk2 = StructuredDeserialize(StructuredSerialize(chunk2)); // } if (!canceled1) { ReadableStreamDefaultControllerEnqueue( branch1._readableStreamController, chunk1 ) } if (!canceled2) { ReadableStreamDefaultControllerEnqueue( branch2._readableStreamController, chunk2 ) } reading = false if (readAgain) { pullAlgorithm() } }) }, _closeSteps: () => { reading = false if (!canceled1) { ReadableStreamDefaultControllerClose( branch1._readableStreamController ) } if (!canceled2) { ReadableStreamDefaultControllerClose( branch2._readableStreamController ) } if (!canceled1 || !canceled2) { resolveCancelPromise(undefined) } }, _errorSteps: () => { reading = false }, } ReadableStreamDefaultReaderRead(reader, readRequest) return promiseResolvedWith(undefined) } function cancel1Algorithm(reason) { canceled1 = true reason1 = reason if (canceled2) { const compositeReason = CreateArrayFromList([reason1, reason2]) const cancelResult = ReadableStreamCancel(stream, compositeReason) resolveCancelPromise(cancelResult) } return cancelPromise } function cancel2Algorithm(reason) { canceled2 = true reason2 = reason if (canceled1) { const compositeReason = CreateArrayFromList([reason1, reason2]) const cancelResult = ReadableStreamCancel(stream, compositeReason) resolveCancelPromise(cancelResult) } return cancelPromise } function startAlgorithm() { // do nothing } branch1 = CreateReadableStream( startAlgorithm, pullAlgorithm, cancel1Algorithm ) branch2 = CreateReadableStream( startAlgorithm, pullAlgorithm, cancel2Algorithm ) uponRejection(reader._closedPromise, (r) => { ReadableStreamDefaultControllerError(branch1._readableStreamController, r) ReadableStreamDefaultControllerError(branch2._readableStreamController, r) if (!canceled1 || !canceled2) { resolveCancelPromise(undefined) } }) return [branch1, branch2] } function ReadableByteStreamTee(stream) { let reader = AcquireReadableStreamDefaultReader(stream) let reading = false let readAgainForBranch1 = false let readAgainForBranch2 = false let canceled1 = false let canceled2 = false let reason1 let reason2 let branch1 let branch2 let resolveCancelPromise const cancelPromise = newPromise((resolve) => { resolveCancelPromise = resolve }) function forwardReaderError(thisReader) { uponRejection(thisReader._closedPromise, (r) => { if (thisReader !== reader) { return } ReadableByteStreamControllerError(branch1._readableStreamController, r) ReadableByteStreamControllerError(branch2._readableStreamController, r) if (!canceled1 || !canceled2) { resolveCancelPromise(undefined) } }) } function pullWithDefaultReader() { if (IsReadableStreamBYOBReader(reader)) { ReadableStreamReaderGenericRelease(reader) reader = AcquireReadableStreamDefaultReader(stream) forwardReaderError(reader) } const readRequest = { _chunkSteps: (chunk) => { // This needs to be delayed a microtask because it takes at least a microtask to detect errors (using // reader._closedPromise below), and we want errors in stream to error both branches immediately. We cannot let // successful synchronously-available reads get ahead of asynchronously-available errors. queueMicrotask(() => { readAgainForBranch1 = false readAgainForBranch2 = false const chunk1 = chunk let chunk2 = chunk if (!canceled1 && !canceled2) { try { chunk2 = CloneAsUint8Array(chunk) } catch (cloneE) { ReadableByteStreamControllerError( branch1._readableStreamController, cloneE ) ReadableByteStreamControllerError( branch2._readableStreamController, cloneE ) resolveCancelPromise(ReadableStreamCancel(stream, cloneE)) return } } if (!canceled1) { ReadableByteStreamControllerEnqueue( branch1._readableStreamController, chunk1 ) } if (!canceled2) { ReadableByteStreamControllerEnqueue( branch2._readableStreamController, chunk2 ) } reading = false if (readAgainForBranch1) { pull1Algorithm() } else if (readAgainForBranch2) { pull2Algorithm() } }) }, _closeSteps: () => { reading = false if (!canceled1) { ReadableByteStreamControllerClose(branch1._readableStreamController) } if (!canceled2) { ReadableByteStreamControllerClose(branch2._readableStreamController) } if (branch1._readableStreamController._pendingPullIntos.length > 0) { ReadableByteStreamControllerRespond( branch1._readableStreamController, 0 ) } if (branch2._readableStreamController._pendingPullIntos.length > 0) { ReadableByteStreamControllerRespond( branch2._readableStreamController, 0 ) } if (!canceled1 || !canceled2) { resolveCancelPromise(undefined) } }, _errorSteps: () => { reading = false }, } ReadableStreamDefaultReaderRead(reader, readRequest) } function pullWithBYOBReader(view, forBranch2) { if (IsReadableStreamDefaultReader(reader)) { ReadableStreamReaderGenericRelease(reader) reader = AcquireReadableStreamBYOBReader(stream) forwardReaderError(reader) } const byobBranch = forBranch2 ? branch2 : branch1 const otherBranch = forBranch2 ? branch1 : branch2 const readIntoRequest = { _chunkSteps: (chunk) => { // This needs to be delayed a microtask because it takes at least a microtask to detect errors (using // reader._closedPromise below), and we want errors in stream to error both branches immediately. We cannot let // successful synchronously-available reads get ahead of asynchronously-available errors. queueMicrotask(() => { readAgainForBranch1 = false readAgainForBranch2 = false const byobCanceled = forBranch2 ? canceled2 : canceled1 const otherCanceled = forBranch2 ? canceled1 : canceled2 if (!otherCanceled) { let clonedChunk try { clonedChunk = CloneAsUint8Array(chunk) } catch (cloneE) { ReadableByteStreamControllerError( byobBranch._readableStreamController, cloneE ) ReadableByteStreamControllerError( otherBranch._readableStreamController, cloneE ) resolveCancelPromise(ReadableStreamCancel(stream, cloneE)) return } if (!byobCanceled) { ReadableByteStreamControllerRespondWithNewView( byobBranch._readableStreamController, chunk ) } ReadableByteStreamControllerEnqueue( otherBranch._readableStreamController, clonedChunk ) } else if (!byobCanceled) { ReadableByteStreamControllerRespondWithNewView( byobBranch._readableStreamController, chunk ) } reading = false if (readAgainForBranch1) { pull1Algorithm() } else if (readAgainForBranch2) { pull2Algorithm() } }) }, _closeSteps: (chunk) => { reading = false const byobCanceled = forBranch2 ? canceled2 : canceled1 const otherCanceled = forBranch2 ? canceled1 : canceled2 if (!byobCanceled) { ReadableByteStreamControllerClose( byobBranch._readableStreamController ) } if (!otherCanceled) { ReadableByteStreamControllerClose( otherBranch._readableStreamController ) } if (chunk !== undefined) { if (!byobCanceled) { ReadableByteStreamControllerRespondWithNewView( byobBranch._readableStreamController, chunk ) } if ( !otherCanceled && otherBranch._readableStreamController._pendingPullIntos.length > 0 ) { ReadableByteStreamControllerRespond( otherBranch._readableStreamController, 0 ) } } if (!byobCanceled || !otherCanceled) { resolveCancelPromise(undefined) } }, _errorSteps: () => { reading = false }, } ReadableStreamBYOBReaderRead(reader, view, readIntoRequest) } function pull1Algorithm() { if (reading) { readAgainForBranch1 = true return promiseResolvedWith(undefined) } reading = true const byobRequest = ReadableByteStreamControllerGetBYOBRequest( branch1._readableStreamController ) if (byobRequest === null) { pullWithDefaultReader() } else { pullWithBYOBReader(byobRequest._view, false) } return promiseResolvedWith(undefined) } function pull2Algorithm() { if (reading) { readAgainForBranch2 = true return promiseResolvedWith(undefined) } reading = true const byobRequest = ReadableByteStreamControllerGetBYOBRequest( branch2._readableStreamController ) if (byobRequest === null) { pullWithDefaultReader() } else { pullWithBYOBReader(byobRequest._view, true) } return promiseResolvedWith(undefined) } function cancel1Algorithm(reason) { canceled1 = true reason1 = reason if (canceled2) { const compositeReason = CreateArrayFromList([reason1, reason2]) const cancelResult = ReadableStreamCancel(stream, compositeReason) resolveCancelPromise(cancelResult) } return cancelPromise } function cancel2Algorithm(reason) { canceled2 = true reason2 = reason if (canceled1) { const compositeReason = CreateArrayFromList([reason1, reason2]) const cancelResult = ReadableStreamCancel(stream, compositeReason) resolveCancelPromise(cancelResult) } return cancelPromise } function startAlgorithm() { return } branch1 = CreateReadableByteStream( startAlgorithm, pull1Algorithm, cancel1Algorithm ) branch2 = CreateReadableByteStream( startAlgorithm, pull2Algorithm, cancel2Algorithm ) forwardReaderError(reader) return [branch1, branch2] } function convertUnderlyingDefaultOrByteSource(source, context) { assertDictionary(source, context) const original = source const autoAllocateChunkSize = original === null || original === void 0 ? void 0 : original.autoAllocateChunkSize const cancel = original === null || original === void 0 ? void 0 : original.cancel const pull = original === null || original === void 0 ? void 0 : original.pull const start = original === null || original === void 0 ? void 0 : original.start const type = original === null || original === void 0 ? void 0 : original.type return { autoAllocateChunkSize: autoAllocateChunkSize === undefined ? undefined : convertUnsignedLongLongWithEnforceRange( autoAllocateChunkSize, `${context} has member 'autoAllocateChunkSize' that` ), cancel: cancel === undefined ? undefined : convertUnderlyingSourceCancelCallback( cancel, original, `${context} has member 'cancel' that` ), pull: pull === undefined ? undefined : convertUnderlyingSourcePullCallback( pull, original, `${context} has member 'pull' that` ), start: start === undefined ? undefined : convertUnderlyingSourceStartCallback( start, original, `${context} has member 'start' that` ), type: type === undefined ? undefined : convertReadableStreamType(type, `${context} has member 'type' that`), } } function convertUnderlyingSourceCancelCallback(fn, original, context) { assertFunction(fn, context) return (reason) => promiseCall(fn, original, [reason]) } function convertUnderlyingSourcePullCallback(fn, original, context) { assertFunction(fn, context) return (controller) => promiseCall(fn, original, [controller]) } function convertUnderlyingSourceStartCallback(fn, original, context) { assertFunction(fn, context) return (controller) => reflectCall(fn, original, [controller]) } function convertReadableStreamType(type, context) { type = `${type}` if (type !== 'bytes') { throw new TypeError( `${context} '${type}' is not a valid enumeration value for ReadableStreamType` ) } return type } function convertReaderOptions(options, context) { assertDictionary(options, context) const mode = options === null || options === void 0 ? void 0 : options.mode return { mode: mode === undefined ? undefined : convertReadableStreamReaderMode( mode, `${context} has member 'mode' that` ), } } function convertReadableStreamReaderMode(mode, context) { mode = `${mode}` if (mode !== 'byob') { throw new TypeError( `${context} '${mode}' is not a valid enumeration value for ReadableStreamReaderMode` ) } return mode } function convertIteratorOptions(options, context) { assertDictionary(options, context) const preventCancel = options === null || options === void 0 ? void 0 : options.preventCancel return { preventCancel: Boolean(preventCancel) } } function convertPipeOptions(options, context) { assertDictionary(options, context) const preventAbort = options === null || options === void 0 ? void 0 : options.preventAbort const preventCancel = options === null || options === void 0 ? void 0 : options.preventCancel const preventClose = options === null || options === void 0 ? void 0 : options.preventClose const signal = options === null || options === void 0 ? void 0 : options.signal if (signal !== undefined) { assertAbortSignal(signal, `${context} has member 'signal' that`) } return { preventAbort: Boolean(preventAbort), preventCancel: Boolean(preventCancel), preventClose: Boolean(preventClose), signal, } } function assertAbortSignal(signal, context) { if (!isAbortSignal$1(signal)) { throw new TypeError(`${context} is not an AbortSignal.`) } } function convertReadableWritablePair(pair, context) { assertDictionary(pair, context) const readable = pair === null || pair === void 0 ? void 0 : pair.readable assertRequiredField(readable, 'readable', 'ReadableWritablePair') assertReadableStream(readable, `${context} has member 'readable' that`) const writable = pair === null || pair === void 0 ? void 0 : pair.writable assertRequiredField(writable, 'writable', 'ReadableWritablePair') assertWritableStream(writable, `${context} has member 'writable' that`) return { readable, writable } } /** * A readable stream represents a source of data, from which you can read. * * @public */ class ReadableStream { constructor(rawUnderlyingSource = {}, rawStrategy = {}) { if (rawUnderlyingSource === undefined) { rawUnderlyingSource = null } else { assertObject(rawUnderlyingSource, 'First parameter') } const strategy = convertQueuingStrategy(rawStrategy, 'Second parameter') const underlyingSource = convertUnderlyingDefaultOrByteSource( rawUnderlyingSource, 'First parameter' ) InitializeReadableStream(this) if (underlyingSource.type === 'bytes') { if (strategy.size !== undefined) { throw new RangeError( 'The strategy for a byte stream cannot have a size function' ) } const highWaterMark = ExtractHighWaterMark(strategy, 0) SetUpReadableByteStreamControllerFromUnderlyingSource( this, underlyingSource, highWaterMark ) } else { const sizeAlgorithm = ExtractSizeAlgorithm(strategy) const highWaterMark = ExtractHighWaterMark(strategy, 1) SetUpReadableStreamDefaultControllerFromUnderlyingSource( this, underlyingSource, highWaterMark, sizeAlgorithm ) } } /** * Whether or not the readable stream is locked to a {@link ReadableStreamDefaultReader | reader}. */ get locked() { if (!IsReadableStream(this)) { throw streamBrandCheckException$1('locked') } return IsReadableStreamLocked(this) } /** * Cancels the stream, signaling a loss of interest in the stream by a consumer. * * The supplied `reason` argument will be given to the underlying source's {@link UnderlyingSource.cancel | cancel()} * method, which might or might not use it. */ cancel(reason = undefined) { if (!IsReadableStream(this)) { return promiseRejectedWith(streamBrandCheckException$1('cancel')) } if (IsReadableStreamLocked(this)) { return promiseRejectedWith( new TypeError('Cannot cancel a stream that already has a reader') ) } return ReadableStreamCancel(this, reason) } getReader(rawOptions = undefined) { if (!IsReadableStream(this)) { throw streamBrandCheckException$1('getReader') } const options = convertReaderOptions(rawOptions, 'First parameter') if (options.mode === undefined) { return AcquireReadableStreamDefaultReader(this) } return AcquireReadableStreamBYOBReader(this) } pipeThrough(rawTransform, rawOptions = {}) { if (!IsReadableStream(this)) { throw streamBrandCheckException$1('pipeThrough') } assertRequiredArgument(rawTransform, 1, 'pipeThrough') const transform = convertReadableWritablePair( rawTransform, 'First parameter' ) const options = convertPipeOptions(rawOptions, 'Second parameter') if (IsReadableStreamLocked(this)) { throw new TypeError( 'ReadableStream.prototype.pipeThrough cannot be used on a locked ReadableStream' ) } if (IsWritableStreamLocked(transform.writable)) { throw new TypeError( 'ReadableStream.prototype.pipeThrough cannot be used on a locked WritableStream' ) } const promise = ReadableStreamPipeTo( this, transform.writable, options.preventClose, options.preventAbort, options.preventCancel, options.signal ) setPromiseIsHandledToTrue(promise) return transform.readable } pipeTo(destination, rawOptions = {}) { if (!IsReadableStream(this)) { return promiseRejectedWith(streamBrandCheckException$1('pipeTo')) } if (destination === undefined) { return promiseRejectedWith(`Parameter 1 is required in 'pipeTo'.`) } if (!IsWritableStream(destination)) { return promiseRejectedWith( new TypeError( `ReadableStream.prototype.pipeTo's first argument must be a WritableStream` ) ) } let options try { options = convertPipeOptions(rawOptions, 'Second parameter') } catch (e) { return promiseRejectedWith(e) } if (IsReadableStreamLocked(this)) { return promiseRejectedWith( new TypeError( 'ReadableStream.prototype.pipeTo cannot be used on a locked ReadableStream' ) ) } if (IsWritableStreamLocked(destination)) { return promiseRejectedWith( new TypeError( 'ReadableStream.prototype.pipeTo cannot be used on a locked WritableStream' ) ) } return ReadableStreamPipeTo( this, destination, options.preventClose, options.preventAbort, options.preventCancel, options.signal ) } /** * Tees this readable stream, returning a two-element array containing the two resulting branches as * new {@link ReadableStream} instances. * * Teeing a stream will lock it, preventing any other consumer from acquiring a reader. * To cancel the stream, cancel both of the resulting branches; a composite cancellation reason will then be * propagated to the stream's underlying source. * * Note that the chunks seen in each branch will be the same object. If the chunks are not immutable, * this could allow interference between the two branches. */ tee() { if (!IsReadableStream(this)) { throw streamBrandCheckException$1('tee') } const branches = ReadableStreamTee(this) return CreateArrayFromList(branches) } values(rawOptions = undefined) { if (!IsReadableStream(this)) { throw streamBrandCheckException$1('values') } const options = convertIteratorOptions(rawOptions, 'First parameter') return AcquireReadableStreamAsyncIterator(this, options.preventCancel) } } Object.defineProperties(ReadableStream.prototype, { cancel: { enumerable: true }, getReader: { enumerable: true }, pipeThrough: { enumerable: true }, pipeTo: { enumerable: true }, tee: { enumerable: true }, values: { enumerable: true }, locked: { enumerable: true }, }) // Abstract operations for the ReadableStream. // Throws if and only if startAlgorithm throws. function CreateReadableStream( startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark = 1, sizeAlgorithm = () => 1 ) { const stream = Object.create(ReadableStream.prototype) InitializeReadableStream(stream) const controller = Object.create(ReadableStreamDefaultController.prototype) SetUpReadableStreamDefaultController( stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, sizeAlgorithm ) return stream } // Throws if and only if startAlgorithm throws. function CreateReadableByteStream( startAlgorithm, pullAlgorithm, cancelAlgorithm ) { const stream = Object.create(ReadableStream.prototype) InitializeReadableStream(stream) const controller = Object.create(ReadableByteStreamController.prototype) SetUpReadableByteStreamController( stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, 0, undefined ) return stream } function InitializeReadableStream(stream) { stream._state = 'readable' stream._reader = undefined stream._storedError = undefined stream._disturbed = false } function IsReadableStream(x) { if (!typeIsObject(x)) { return false } if (!Object.prototype.hasOwnProperty.call(x, '_readableStreamController')) { return false } return x instanceof ReadableStream } function IsReadableStreamLocked(stream) { if (stream._reader === undefined) { return false } return true } // ReadableStream API exposed for controllers. function ReadableStreamCancel(stream, reason) { stream._disturbed = true if (stream._state === 'closed') { return promiseResolvedWith(undefined) } if (stream._state === 'errored') { return promiseRejectedWith(stream._storedError) } ReadableStreamClose(stream) const reader = stream._reader if (reader !== undefined && IsReadableStreamBYOBReader(reader)) { reader._readIntoRequests.forEach((readIntoRequest) => { readIntoRequest._closeSteps(undefined) }) reader._readIntoRequests = new SimpleQueue() } const sourceCancelPromise = stream._readableStreamController[CancelSteps](reason) return transformPromiseWith(sourceCancelPromise, noop$1) } function ReadableStreamClose(stream) { stream._state = 'closed' const reader = stream._reader if (reader === undefined) { return } defaultReaderClosedPromiseResolve(reader) if (IsReadableStreamDefaultReader(reader)) { reader._readRequests.forEach((readRequest) => { readRequest._closeSteps() }) reader._readRequests = new SimpleQueue() } } function ReadableStreamError(stream, e) { stream._state = 'errored' stream._storedError = e const reader = stream._reader if (reader === undefined) { return } defaultReaderClosedPromiseReject(reader, e) if (IsReadableStreamDefaultReader(reader)) { reader._readRequests.forEach((readRequest) => { readRequest._errorSteps(e) }) reader._readRequests = new SimpleQueue() } else { reader._readIntoRequests.forEach((readIntoRequest) => { readIntoRequest._errorSteps(e) }) reader._readIntoRequests = new SimpleQueue() } } // Helper functions for the ReadableStream. function streamBrandCheckException$1(name) { return new TypeError( `ReadableStream.prototype.${name} can only be used on a ReadableStream` ) } function convertQueuingStrategyInit(init, context) { assertDictionary(init, context) const highWaterMark = init === null || init === void 0 ? void 0 : init.highWaterMark assertRequiredField(highWaterMark, 'highWaterMark', 'QueuingStrategyInit') return { highWaterMark: convertUnrestrictedDouble(highWaterMark), } } // The size function must not have a prototype property nor be a constructor const byteLengthSizeFunction = (chunk) => { return chunk.byteLength } Object.defineProperty(byteLengthSizeFunction, 'name', { value: 'size', configurable: true, }) /** * A queuing strategy that counts the number of bytes in each chunk. * * @public */ class ByteLengthQueuingStrategy { constructor(options) { assertRequiredArgument(options, 1, 'ByteLengthQueuingStrategy') options = convertQueuingStrategyInit(options, 'First parameter') this._byteLengthQueuingStrategyHighWaterMark = options.highWaterMark } /** * Returns the high water mark provided to the constructor. */ get highWaterMark() { if (!IsByteLengthQueuingStrategy(this)) { throw byteLengthBrandCheckException('highWaterMark') } return this._byteLengthQueuingStrategyHighWaterMark } /** * Measures the size of `chunk` by returning the value of its `byteLength` property. */ get size() { if (!IsByteLengthQueuingStrategy(this)) { throw byteLengthBrandCheckException('size') } return byteLengthSizeFunction } } Object.defineProperties(ByteLengthQueuingStrategy.prototype, { highWaterMark: { enumerable: true }, size: { enumerable: true }, }) // Helper functions for the ByteLengthQueuingStrategy. function byteLengthBrandCheckException(name) { return new TypeError( `ByteLengthQueuingStrategy.prototype.${name} can only be used on a ByteLengthQueuingStrategy` ) } function IsByteLengthQueuingStrategy(x) { if (!typeIsObject(x)) { return false } if ( !Object.prototype.hasOwnProperty.call( x, '_byteLengthQueuingStrategyHighWaterMark' ) ) { return false } return x instanceof ByteLengthQueuingStrategy } // The size function must not have a prototype property nor be a constructor const countSizeFunction = () => { return 1 } Object.defineProperty(countSizeFunction, 'name', { value: 'size', configurable: true, }) /** * A queuing strategy that counts the number of chunks. * * @public */ class CountQueuingStrategy { constructor(options) { assertRequiredArgument(options, 1, 'CountQueuingStrategy') options = convertQueuingStrategyInit(options, 'First parameter') this._countQueuingStrategyHighWaterMark = options.highWaterMark } /** * Returns the high water mark provided to the constructor. */ get highWaterMark() { if (!IsCountQueuingStrategy(this)) { throw countBrandCheckException('highWaterMark') } return this._countQueuingStrategyHighWaterMark } /** * Measures the size of `chunk` by always returning 1. * This ensures that the total queue size is a count of the number of chunks in the queue. */ get size() { if (!IsCountQueuingStrategy(this)) { throw countBrandCheckException('size') } return countSizeFunction } } Object.defineProperties(CountQueuingStrategy.prototype, { highWaterMark: { enumerable: true }, size: { enumerable: true }, }) // Helper functions for the CountQueuingStrategy. function countBrandCheckException(name) { return new TypeError( `CountQueuingStrategy.prototype.${name} can only be used on a CountQueuingStrategy` ) } function IsCountQueuingStrategy(x) { if (!typeIsObject(x)) { return false } if ( !Object.prototype.hasOwnProperty.call( x, '_countQueuingStrategyHighWaterMark' ) ) { return false } return x instanceof CountQueuingStrategy } function convertTransformer(original, context) { assertDictionary(original, context) const flush = original === null || original === void 0 ? void 0 : original.flush const readableType = original === null || original === void 0 ? void 0 : original.readableType const start = original === null || original === void 0 ? void 0 : original.start const transform = original === null || original === void 0 ? void 0 : original.transform const writableType = original === null || original === void 0 ? void 0 : original.writableType return { flush: flush === undefined ? undefined : convertTransformerFlushCallback( flush, original, `${context} has member 'flush' that` ), readableType, start: start === undefined ? undefined : convertTransformerStartCallback( start, original, `${context} has member 'start' that` ), transform: transform === undefined ? undefined : convertTransformerTransformCallback( transform, original, `${context} has member 'transform' that` ), writableType, } } function convertTransformerFlushCallback(fn, original, context) { assertFunction(fn, context) return (controller) => promiseCall(fn, original, [controller]) } function convertTransformerStartCallback(fn, original, context) { assertFunction(fn, context) return (controller) => reflectCall(fn, original, [controller]) } function convertTransformerTransformCallback(fn, original, context) { assertFunction(fn, context) return (chunk, controller) => promiseCall(fn, original, [chunk, controller]) } // Class TransformStream /** * A transform stream consists of a pair of streams: a {@link WritableStream | writable stream}, * known as its writable side, and a {@link ReadableStream | readable stream}, known as its readable side. * In a manner specific to the transform stream in question, writes to the writable side result in new data being * made available for reading from the readable side. * * @public */ class TransformStream { constructor( rawTransformer = {}, rawWritableStrategy = {}, rawReadableStrategy = {} ) { if (rawTransformer === undefined) { rawTransformer = null } const writableStrategy = convertQueuingStrategy( rawWritableStrategy, 'Second parameter' ) const readableStrategy = convertQueuingStrategy( rawReadableStrategy, 'Third parameter' ) const transformer = convertTransformer(rawTransformer, 'First parameter') if (transformer.readableType !== undefined) { throw new RangeError('Invalid readableType specified') } if (transformer.writableType !== undefined) { throw new RangeError('Invalid writableType specified') } const readableHighWaterMark = ExtractHighWaterMark(readableStrategy, 0) const readableSizeAlgorithm = ExtractSizeAlgorithm(readableStrategy) const writableHighWaterMark = ExtractHighWaterMark(writableStrategy, 1) const writableSizeAlgorithm = ExtractSizeAlgorithm(writableStrategy) let startPromise_resolve const startPromise = newPromise((resolve) => { startPromise_resolve = resolve }) InitializeTransformStream( this, startPromise, writableHighWaterMark, writableSizeAlgorithm, readableHighWaterMark, readableSizeAlgorithm ) SetUpTransformStreamDefaultControllerFromTransformer(this, transformer) if (transformer.start !== undefined) { startPromise_resolve(transformer.start(this._transformStreamController)) } else { startPromise_resolve(undefined) } } /** * The readable side of the transform stream. */ get readable() { if (!IsTransformStream(this)) { throw streamBrandCheckException('readable') } return this._readable } /** * The writable side of the transform stream. */ get writable() { if (!IsTransformStream(this)) { throw streamBrandCheckException('writable') } return this._writable } } Object.defineProperties(TransformStream.prototype, { readable: { enumerable: true }, writable: { enumerable: true }, }) function InitializeTransformStream( stream, startPromise, writableHighWaterMark, writableSizeAlgorithm, readableHighWaterMark, readableSizeAlgorithm ) { function startAlgorithm() { return startPromise } function writeAlgorithm(chunk) { return TransformStreamDefaultSinkWriteAlgorithm(stream, chunk) } function abortAlgorithm(reason) { return TransformStreamDefaultSinkAbortAlgorithm(stream, reason) } function closeAlgorithm() { return TransformStreamDefaultSinkCloseAlgorithm(stream) } stream._writable = CreateWritableStream( startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, writableHighWaterMark, writableSizeAlgorithm ) function pullAlgorithm() { return TransformStreamDefaultSourcePullAlgorithm(stream) } function cancelAlgorithm(reason) { TransformStreamErrorWritableAndUnblockWrite(stream, reason) return promiseResolvedWith(undefined) } stream._readable = CreateReadableStream( startAlgorithm, pullAlgorithm, cancelAlgorithm, readableHighWaterMark, readableSizeAlgorithm ) // The [[backpressure]] slot is set to undefined so that it can be initialised by TransformStreamSetBackpressure. stream._backpressure = undefined stream._backpressureChangePromise = undefined stream._backpressureChangePromise_resolve = undefined TransformStreamSetBackpressure(stream, true) stream._transformStreamController = undefined } function IsTransformStream(x) { if (!typeIsObject(x)) { return false } if (!Object.prototype.hasOwnProperty.call(x, '_transformStreamController')) { return false } return x instanceof TransformStream } // This is a no-op if both sides are already errored. function TransformStreamError(stream, e) { ReadableStreamDefaultControllerError( stream._readable._readableStreamController, e ) TransformStreamErrorWritableAndUnblockWrite(stream, e) } function TransformStreamErrorWritableAndUnblockWrite(stream, e) { TransformStreamDefaultControllerClearAlgorithms( stream._transformStreamController ) WritableStreamDefaultControllerErrorIfNeeded( stream._writable._writableStreamController, e ) if (stream._backpressure) { // Pretend that pull() was called to permit any pending write() calls to complete. TransformStreamSetBackpressure() // cannot be called from enqueue() or pull() once the ReadableStream is errored, so this will will be the final time // _backpressure is set. TransformStreamSetBackpressure(stream, false) } } function TransformStreamSetBackpressure(stream, backpressure) { // Passes also when called during construction. if (stream._backpressureChangePromise !== undefined) { stream._backpressureChangePromise_resolve() } stream._backpressureChangePromise = newPromise((resolve) => { stream._backpressureChangePromise_resolve = resolve }) stream._backpressure = backpressure } // Class TransformStreamDefaultController /** * Allows control of the {@link ReadableStream} and {@link WritableStream} of the associated {@link TransformStream}. * * @public */ class TransformStreamDefaultController { constructor() { throw new TypeError('Illegal constructor') } /** * Returns the desired size to fill the readable side’s internal queue. It can be negative, if the queue is over-full. */ get desiredSize() { if (!IsTransformStreamDefaultController(this)) { throw defaultControllerBrandCheckException('desiredSize') } const readableController = this._controlledTransformStream._readable._readableStreamController return ReadableStreamDefaultControllerGetDesiredSize(readableController) } enqueue(chunk = undefined) { if (!IsTransformStreamDefaultController(this)) { throw defaultControllerBrandCheckException('enqueue') } TransformStreamDefaultControllerEnqueue(this, chunk) } /** * Errors both the readable side and the writable side of the controlled transform stream, making all future * interactions with it fail with the given error `e`. Any chunks queued for transformation will be discarded. */ error(reason = undefined) { if (!IsTransformStreamDefaultController(this)) { throw defaultControllerBrandCheckException('error') } TransformStreamDefaultControllerError(this, reason) } /** * Closes the readable side and errors the writable side of the controlled transform stream. This is useful when the * transformer only needs to consume a portion of the chunks written to the writable side. */ terminate() { if (!IsTransformStreamDefaultController(this)) { throw defaultControllerBrandCheckException('terminate') } TransformStreamDefaultControllerTerminate(this) } } Object.defineProperties(TransformStreamDefaultController.prototype, { enqueue: { enumerable: true }, error: { enumerable: true }, terminate: { enumerable: true }, desiredSize: { enumerable: true }, }) // Transform Stream Default Controller Abstract Operations function IsTransformStreamDefaultController(x) { if (!typeIsObject(x)) { return false } if (!Object.prototype.hasOwnProperty.call(x, '_controlledTransformStream')) { return false } return x instanceof TransformStreamDefaultController } function SetUpTransformStreamDefaultController( stream, controller, transformAlgorithm, flushAlgorithm ) { controller._controlledTransformStream = stream stream._transformStreamController = controller controller._transformAlgorithm = transformAlgorithm controller._flushAlgorithm = flushAlgorithm } function SetUpTransformStreamDefaultControllerFromTransformer( stream, transformer ) { const controller = Object.create(TransformStreamDefaultController.prototype) let transformAlgorithm = (chunk) => { try { TransformStreamDefaultControllerEnqueue(controller, chunk) return promiseResolvedWith(undefined) } catch (transformResultE) { return promiseRejectedWith(transformResultE) } } let flushAlgorithm = () => promiseResolvedWith(undefined) if (transformer.transform !== undefined) { transformAlgorithm = (chunk) => transformer.transform(chunk, controller) } if (transformer.flush !== undefined) { flushAlgorithm = () => transformer.flush(controller) } SetUpTransformStreamDefaultController( stream, controller, transformAlgorithm, flushAlgorithm ) } function TransformStreamDefaultControllerClearAlgorithms(controller) { controller._transformAlgorithm = undefined controller._flushAlgorithm = undefined } function TransformStreamDefaultControllerEnqueue(controller, chunk) { const stream = controller._controlledTransformStream const readableController = stream._readable._readableStreamController if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(readableController)) { throw new TypeError('Readable side is not in a state that permits enqueue') } // We throttle transform invocations based on the backpressure of the ReadableStream, but we still // accept TransformStreamDefaultControllerEnqueue() calls. try { ReadableStreamDefaultControllerEnqueue(readableController, chunk) } catch (e) { // This happens when readableStrategy.size() throws. TransformStreamErrorWritableAndUnblockWrite(stream, e) throw stream._readable._storedError } const backpressure = ReadableStreamDefaultControllerHasBackpressure(readableController) if (backpressure !== stream._backpressure) { TransformStreamSetBackpressure(stream, true) } } function TransformStreamDefaultControllerError(controller, e) { TransformStreamError(controller._controlledTransformStream, e) } function TransformStreamDefaultControllerPerformTransform(controller, chunk) { const transformPromise = controller._transformAlgorithm(chunk) return transformPromiseWith(transformPromise, undefined, (r) => { TransformStreamError(controller._controlledTransformStream, r) throw r }) } function TransformStreamDefaultControllerTerminate(controller) { const stream = controller._controlledTransformStream const readableController = stream._readable._readableStreamController ReadableStreamDefaultControllerClose(readableController) const error = new TypeError('TransformStream terminated') TransformStreamErrorWritableAndUnblockWrite(stream, error) } // TransformStreamDefaultSink Algorithms function TransformStreamDefaultSinkWriteAlgorithm(stream, chunk) { const controller = stream._transformStreamController if (stream._backpressure) { const backpressureChangePromise = stream._backpressureChangePromise return transformPromiseWith(backpressureChangePromise, () => { const writable = stream._writable const state = writable._state if (state === 'erroring') { throw writable._storedError } return TransformStreamDefaultControllerPerformTransform(controller, chunk) }) } return TransformStreamDefaultControllerPerformTransform(controller, chunk) } function TransformStreamDefaultSinkAbortAlgorithm(stream, reason) { // abort() is not called synchronously, so it is possible for abort() to be called when the stream is already // errored. TransformStreamError(stream, reason) return promiseResolvedWith(undefined) } function TransformStreamDefaultSinkCloseAlgorithm(stream) { // stream._readable cannot change after construction, so caching it across a call to user code is safe. const readable = stream._readable const controller = stream._transformStreamController const flushPromise = controller._flushAlgorithm() TransformStreamDefaultControllerClearAlgorithms(controller) // Return a promise that is fulfilled with undefined on success. return transformPromiseWith( flushPromise, () => { if (readable._state === 'errored') { throw readable._storedError } ReadableStreamDefaultControllerClose(readable._readableStreamController) }, (r) => { TransformStreamError(stream, r) throw readable._storedError } ) } // TransformStreamDefaultSource Algorithms function TransformStreamDefaultSourcePullAlgorithm(stream) { // Invariant. Enforced by the promises returned by start() and pull(). TransformStreamSetBackpressure(stream, false) // Prevent the next pull() call until there is backpressure. return stream._backpressureChangePromise } // Helper functions for the TransformStreamDefaultController. function defaultControllerBrandCheckException(name) { return new TypeError( `TransformStreamDefaultController.prototype.${name} can only be used on a TransformStreamDefaultController` ) } // Helper functions for the TransformStream. function streamBrandCheckException(name) { return new TypeError( `TransformStream.prototype.${name} can only be used on a TransformStream` ) } /* c8 ignore start */ // 64 KiB (same size chrome slice theirs blob into Uint8array's) const POOL_SIZE$1 = 65536 try { // Don't use node: prefix for this, require+node: is not supported until node v14.14 // Only `import()` can use prefix in 12.20 and later const { Blob } = require('buffer') if (Blob && !Blob.prototype.stream) { Blob.prototype.stream = function name(params) { let position = 0 const blob = this return new ReadableStream({ type: 'bytes', async pull(ctrl) { const chunk = blob.slice( position, Math.min(blob.size, position + POOL_SIZE$1) ) const buffer = await chunk.arrayBuffer() position += buffer.byteLength ctrl.enqueue(new Uint8Array(buffer)) if (position === blob.size) { ctrl.close() } }, }) } } } catch (error) {} /* c8 ignore end */ // 64 KiB (same size chrome slice theirs blob into Uint8array's) const POOL_SIZE = 65536 /** @param {(Blob | Uint8Array)[]} parts */ async function* toIterator(parts, clone = true) { for (const part of parts) { if ('stream' in part) { yield* /** @type {AsyncIterableIterator} */ (part.stream()) } else if (ArrayBuffer.isView(part)) { if (clone) { let position = part.byteOffset const end = part.byteOffset + part.byteLength while (position !== end) { const size = Math.min(end - position, POOL_SIZE) const chunk = part.buffer.slice(position, position + size) position += chunk.byteLength yield new Uint8Array(chunk) } } else { yield part } /* c8 ignore next 10 */ } else { // For blobs that have arrayBuffer but no stream method (nodes buffer.Blob) let position = 0, b = /** @type {Blob} */ (part) while (position !== b.size) { const chunk = b.slice(position, Math.min(b.size, position + POOL_SIZE)) const buffer = await chunk.arrayBuffer() position += buffer.byteLength yield new Uint8Array(buffer) } } } } const _Blob = class Blob { /** @type {Array.<(Blob|Uint8Array)>} */ #parts = [] #type = '' #size = 0 #endings = 'transparent' /** * The Blob() constructor returns a new Blob object. The content * of the blob consists of the concatenation of the values given * in the parameter array. * * @param {*} blobParts * @param {{ type?: string, endings?: string }} [options] */ constructor(blobParts = [], options = {}) { if (typeof blobParts !== 'object' || blobParts === null) { throw new TypeError( "Failed to construct 'Blob': The provided value cannot be converted to a sequence." ) } if (typeof blobParts[Symbol.iterator] !== 'function') { throw new TypeError( "Failed to construct 'Blob': The object must have a callable @@iterator property." ) } if (typeof options !== 'object' && typeof options !== 'function') { throw new TypeError( "Failed to construct 'Blob': parameter 2 cannot convert to dictionary." ) } if (options === null) options = {} const encoder = new TextEncoder() for (const element of blobParts) { let part if (ArrayBuffer.isView(element)) { part = new Uint8Array( element.buffer.slice( element.byteOffset, element.byteOffset + element.byteLength ) ) } else if (element instanceof ArrayBuffer) { part = new Uint8Array(element.slice(0)) } else if (element instanceof Blob) { part = element } else { part = encoder.encode(`${element}`) } this.#size += ArrayBuffer.isView(part) ? part.byteLength : part.size this.#parts.push(part) } this.#endings = `${ options.endings === undefined ? 'transparent' : options.endings }` const type = options.type === undefined ? '' : String(options.type) this.#type = /^[\x20-\x7E]*$/.test(type) ? type : '' } /** * The Blob interface's size property returns the * size of the Blob in bytes. */ get size() { return this.#size } /** * The type property of a Blob object returns the MIME type of the file. */ get type() { return this.#type } /** * The text() method in the Blob interface returns a Promise * that resolves with a string containing the contents of * the blob, interpreted as UTF-8. * * @return {Promise} */ async text() { // More optimized than using this.arrayBuffer() // that requires twice as much ram const decoder = new TextDecoder() let str = '' for await (const part of toIterator(this.#parts, false)) { str += decoder.decode(part, { stream: true }) } // Remaining str += decoder.decode() return str } /** * The arrayBuffer() method in the Blob interface returns a * Promise that resolves with the contents of the blob as * binary data contained in an ArrayBuffer. * * @return {Promise} */ async arrayBuffer() { // Easier way... Just a unnecessary overhead // const view = new Uint8Array(this.size); // await this.stream().getReader({mode: 'byob'}).read(view); // return view.buffer; const data = new Uint8Array(this.size) let offset = 0 for await (const chunk of toIterator(this.#parts, false)) { data.set(chunk, offset) offset += chunk.length } return data.buffer } stream() { const it = toIterator(this.#parts, true) return new ReadableStream({ // @ts-ignore type: 'bytes', async pull(ctrl) { const chunk = await it.next() chunk.done ? ctrl.close() : ctrl.enqueue(chunk.value) }, async cancel() { await it.return() }, }) } /** * The Blob interface's slice() method creates and returns a * new Blob object which contains data from a subset of the * blob on which it's called. * * @param {number} [start] * @param {number} [end] * @param {string} [type] */ slice(start = 0, end = this.size, type = '') { const { size } = this let relativeStart = start < 0 ? Math.max(size + start, 0) : Math.min(start, size) let relativeEnd = end < 0 ? Math.max(size + end, 0) : Math.min(end, size) const span = Math.max(relativeEnd - relativeStart, 0) const parts = this.#parts const blobParts = [] let added = 0 for (const part of parts) { // don't add the overflow to new blobParts if (added >= span) { break } const size = ArrayBuffer.isView(part) ? part.byteLength : part.size if (relativeStart && size <= relativeStart) { // Skip the beginning and change the relative // start & end position as we skip the unwanted parts relativeStart -= size relativeEnd -= size } else { let chunk if (ArrayBuffer.isView(part)) { chunk = part.subarray(relativeStart, Math.min(size, relativeEnd)) added += chunk.byteLength } else { chunk = part.slice(relativeStart, Math.min(size, relativeEnd)) added += chunk.size } relativeEnd -= size blobParts.push(chunk) relativeStart = 0 // All next sequential parts should start at 0 } } const blob = new Blob([], { type: String(type).toLowerCase() }) blob.#size = span blob.#parts = blobParts return blob } get [Symbol.toStringTag]() { return 'Blob' } static [Symbol.hasInstance](object) { return ( object && typeof object === 'object' && typeof object.constructor === 'function' && (typeof object.stream === 'function' || typeof object.arrayBuffer === 'function') && /^(Blob|File)$/.test(object[Symbol.toStringTag]) ) } } Object.defineProperties(_Blob.prototype, { size: { enumerable: true }, type: { enumerable: true }, slice: { enumerable: true }, }) /** @type {typeof globalThis.Blob} */ const Blob = _Blob const _File = class File extends Blob { #lastModified = 0 #name = '' /** * @param {*[]} fileBits * @param {string} fileName * @param {{lastModified?: number, type?: string}} options */ // @ts-ignore constructor(fileBits, fileName, options = {}) { if (arguments.length < 2) { throw new TypeError( `Failed to construct 'File': 2 arguments required, but only ${arguments.length} present.` ) } super(fileBits, options) if (options === null) options = {} // Simulate WebIDL type casting for NaN value in lastModified option. const lastModified = options.lastModified === undefined ? Date.now() : Number(options.lastModified) if (!Number.isNaN(lastModified)) { this.#lastModified = lastModified } this.#name = String(fileName) } get name() { return this.#name } get lastModified() { return this.#lastModified } get [Symbol.toStringTag]() { return 'File' } static [Symbol.hasInstance](object) { return ( !!object && object instanceof Blob && /^(File)$/.test(object[Symbol.toStringTag]) ) } } /** @type {typeof globalThis.File} */ // @ts-ignore const File = _File class CustomEvent extends Event { constructor(type, params) { params = Object(params) super(type, params) if ('detail' in params) this.detail = params.detail } } allowStringTag(CustomEvent) class TreeWalker { parentNode() { return null } firstChild() { return null } lastChild() { return null } previousSibling() { return null } nextSibling() { return null } previousNode() { return null } nextNode() { return null } get currentNode() { const internals = internalsOf(this, 'TreeWalker', 'currentNode') return internals.currentNode } get root() { const internals = internalsOf(this, 'TreeWalker', 'root') return internals.root } get whatToShow() { const internals = internalsOf(this, 'TreeWalker', 'whatToShow') return internals.whatToShow } } allowStringTag(TreeWalker) const INTERNAL$1 = { tick: 0, pool: new Map() } function requestIdleCallback(callback) { if (!INTERNAL$1.pool.size) { setTimeout$1(() => { const next = __performance_now() for (const func of INTERNAL$1.pool.values()) { func(next) } INTERNAL$1.pool.clear() }, 1000 / 16) } const func = __function_bind(callback, undefined) const tick = ++INTERNAL$1.tick INTERNAL$1.pool.set(tick, func) return tick } function cancelIdleCallback(requestId) { const timeout = INTERNAL$1.pool.get(requestId) if (timeout) { clearTimeout$1(timeout) INTERNAL$1.pool.delete(requestId) } } /** * Returns a `Buffer` instance from the given data URI `uri`. * * @param {String} uri Data URI to turn into a Buffer instance * @returns {Buffer} Buffer instance from Data URI * @api public */ function dataUriToBuffer(uri) { if (!/^data:/i.test(uri)) { throw new TypeError( '`uri` does not appear to be a Data URI (must begin with "data:")' ) } // strip newlines uri = uri.replace(/\r?\n/g, '') // split the URI up into the "metadata" and the "data" portions const firstComma = uri.indexOf(',') if (firstComma === -1 || firstComma <= 4) { throw new TypeError('malformed data: URI') } // remove the "data:" scheme and parse the metadata const meta = uri.substring(5, firstComma).split(';') let charset = '' let base64 = false const type = meta[0] || 'text/plain' let typeFull = type for (let i = 1; i < meta.length; i++) { if (meta[i] === 'base64') { base64 = true } else { typeFull += `;${meta[i]}` if (meta[i].indexOf('charset=') === 0) { charset = meta[i].substring(8) } } } // defaults to US-ASCII only if type is not provided if (!meta[0] && !charset.length) { typeFull += ';charset=US-ASCII' charset = 'US-ASCII' } // get the encoded data portion and decode URI-encoded chars const encoding = base64 ? 'base64' : 'ascii' const data = unescape(uri.substring(firstComma + 1)) const buffer = Buffer.from(data, encoding) // set `.type` and `.typeFull` properties to MIME type buffer.type = type buffer.typeFull = typeFull // set the `.charset` property buffer.charset = charset return buffer } /*! formdata-polyfill. MIT License. Jimmy Wärting */ var { toStringTag: t$1, iterator: i$1, hasInstance: h$1 } = Symbol, r$1 = Math.random, m$1 = 'append,set,get,getAll,delete,keys,values,entries,forEach,constructor'.split( ',' ), f$2 = (a, b, c) => ( (a += ''), /^(Blob|File)$/.test(b && b[t$1]) ? [ ((c = c !== void 0 ? c + '' : b[t$1] == 'File' ? b.name : 'blob'), a), b.name !== c || b[t$1] == 'blob' ? new File([b], c, b) : b, ] : [a, b + ''] ), e$1 = (c, f) => (f ? c : c.replace(/\r?\n|\r/g, '\r\n')) .replace(/\n/g, '%0A') .replace(/\r/g, '%0D') .replace(/"/g, '%22'), x$1 = (n, a, e) => { if (a.length < e) { throw new TypeError( `Failed to execute '${n}' on 'FormData': ${e} arguments required, but only ${a.length} present.` ) } } /** @type {typeof globalThis.FormData} */ const FormData = class FormData { #d = [] constructor(...a) { if (a.length) throw new TypeError( `Failed to construct 'FormData': parameter 1 is not of type 'HTMLFormElement'.` ) } get [t$1]() { return 'FormData' } [i$1]() { return this.entries() } static [h$1](o) { return ( o && typeof o === 'object' && o[t$1] === 'FormData' && !m$1.some((m) => typeof o[m] != 'function') ) } append(...a) { x$1('append', arguments, 2) this.#d.push(f$2(...a)) } delete(a) { x$1('delete', arguments, 1) a += '' this.#d = this.#d.filter(([b]) => b !== a) } get(a) { x$1('get', arguments, 1) a += '' for (var b = this.#d, l = b.length, c = 0; c < l; c++) if (b[c][0] === a) return b[c][1] return null } getAll(a, b) { x$1('getAll', arguments, 1) b = [] a += '' this.#d.forEach((c) => c[0] === a && b.push(c[1])) return b } has(a) { x$1('has', arguments, 1) a += '' return this.#d.some((b) => b[0] === a) } forEach(a, b) { x$1('forEach', arguments, 1) for (var [c, d] of this) a.call(b, d, c, this) } set(...a) { x$1('set', arguments, 2) var b = [], c = !0 a = f$2(...a) this.#d.forEach((d) => { d[0] === a[0] ? c && (c = !b.push(a)) : b.push(d) }) c && b.push(a) this.#d = b } *entries() { yield* this.#d } *keys() { for (var [a] of this) yield a } *values() { for (var [, a] of this) yield a } } /** @param {FormData} F */ function formDataToBlob(F, B = Blob) { var b = `${r$1()}${r$1()}`.replace(/\./g, '').slice(-28).padStart(32, '-'), c = [], p = `--${b}\r\nContent-Disposition: form-data; name="` F.forEach((v, n) => typeof v == 'string' ? c.push( p + e$1(n) + `"\r\n\r\n${v.replace(/\r(?!\n)|(? { return ( typeof object === 'object' && typeof object.append === 'function' && typeof object.delete === 'function' && typeof object.get === 'function' && typeof object.getAll === 'function' && typeof object.has === 'function' && typeof object.set === 'function' && typeof object.sort === 'function' && object[NAME] === 'URLSearchParams' ) } /** * Check if `object` is a W3C `Blob` object (which `File` inherits from) * @param {*} object - Object to check for * @return {boolean} */ const isBlob = (object) => { return ( object && typeof object === 'object' && typeof object.arrayBuffer === 'function' && typeof object.type === 'string' && typeof object.stream === 'function' && typeof object.constructor === 'function' && /^(Blob|File)$/.test(object[NAME]) ) } /** * Check if `obj` is an instance of AbortSignal. * @param {*} object - Object to check for * @return {boolean} */ const isAbortSignal = (object) => { return ( typeof object === 'object' && (object[NAME] === 'AbortSignal' || object[NAME] === 'EventTarget') ) } /** * isDomainOrSubdomain reports whether sub is a subdomain (or exact match) of * the parent domain. * * Both domains must already be in canonical form. * @param {string|URL} original * @param {string|URL} destination */ const isDomainOrSubdomain = (destination, original) => { const orig = new URL(original).hostname const dest = new URL(destination).hostname return orig === dest || orig.endsWith(`.${dest}`) } const pipeline = promisify(Stream.pipeline) const INTERNALS$2 = Symbol('Body internals') /** * Body mixin * * Ref: https://fetch.spec.whatwg.org/#body * * @param Stream body Readable stream * @param Object opts Response options * @return Void */ class Body { constructor(body, { size = 0 } = {}) { let boundary = null if (body === null) { // Body is undefined or null body = null } else if (isURLSearchParameters(body)) { // Body is a URLSearchParams body = Buffer.from(body.toString()) } else if (isBlob(body)); else if (Buffer.isBuffer(body)); else if (types.isAnyArrayBuffer(body)) { // Body is ArrayBuffer body = Buffer.from(body) } else if (ArrayBuffer.isView(body)) { // Body is ArrayBufferView body = Buffer.from(body.buffer, body.byteOffset, body.byteLength) } else if (body instanceof Stream); else if (body instanceof FormData) { // Body is FormData body = formDataToBlob(body) boundary = body.type.split('=')[1] } else { // None of the above // coerce to string then buffer body = Buffer.from(String(body)) } let stream = body if (Buffer.isBuffer(body)) { stream = Stream.Readable.from(body) } else if (isBlob(body)) { stream = Stream.Readable.from(body.stream()) } this[INTERNALS$2] = { body, stream, boundary, disturbed: false, error: null, } this.size = size if (body instanceof Stream) { body.on('error', (error_) => { const error = error_ instanceof FetchBaseError ? error_ : new FetchError( `Invalid response body while trying to fetch ${this.url}: ${error_.message}`, 'system', error_ ) this[INTERNALS$2].error = error }) } } get body() { return this[INTERNALS$2].stream } get bodyUsed() { return this[INTERNALS$2].disturbed } /** * Decode response as ArrayBuffer * * @return Promise */ async arrayBuffer() { const { buffer, byteOffset, byteLength } = await consumeBody(this) return buffer.slice(byteOffset, byteOffset + byteLength) } async formData() { const ct = this.headers.get('content-type') if (ct.startsWith('application/x-www-form-urlencoded')) { const formData = new FormData() const parameters = new URLSearchParams(await this.text()) for (const [name, value] of parameters) { formData.append(name, value) } return formData } const { toFormData } = await Promise.resolve().then(function () { return multipartParser }) return toFormData(this.body, ct) } /** * Return raw response as Blob * * @return Promise */ async blob() { const ct = (this.headers && this.headers.get('content-type')) || (this[INTERNALS$2].body && this[INTERNALS$2].body.type) || '' const buf = await this.arrayBuffer() return new Blob([buf], { type: ct, }) } /** * Decode response as json * * @return Promise */ async json() { const buffer = await consumeBody(this) return JSON.parse(buffer.toString()) } /** * Decode response as text * * @return Promise */ async text() { const buffer = await consumeBody(this) return buffer.toString() } /** * Decode response as buffer (non-spec api) * * @return Promise */ buffer() { return consumeBody(this) } } // In browsers, all properties are enumerable. Object.defineProperties(Body.prototype, { body: { enumerable: true }, bodyUsed: { enumerable: true }, arrayBuffer: { enumerable: true }, blob: { enumerable: true }, json: { enumerable: true }, text: { enumerable: true }, }) /** * Consume and convert an entire Body to a Buffer. * * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body * * @return Promise */ async function consumeBody(data) { if (data[INTERNALS$2].disturbed) { throw new TypeError(`body used already for: ${data.url}`) } data[INTERNALS$2].disturbed = true if (data[INTERNALS$2].error) { throw data[INTERNALS$2].error } const { body } = data // Body is null if (body === null) { return Buffer.alloc(0) } /* c8 ignore next 3 */ if (!(body instanceof Stream)) { return Buffer.alloc(0) } // Body is stream // get ready to actually consume the body const accum = [] let accumBytes = 0 try { for await (const chunk of body) { if (data.size > 0 && accumBytes + chunk.length > data.size) { const error = new FetchError( `content size at ${data.url} over limit: ${data.size}`, 'max-size' ) body.destroy(error) throw error } accumBytes += chunk.length accum.push(chunk) } } catch (error) { const error_ = error instanceof FetchBaseError ? error : new FetchError( `Invalid response body while trying to fetch ${data.url}: ${error.message}`, 'system', error ) throw error_ } if (body.readableEnded === true || body._readableState.ended === true) { try { if (accum.every((c) => typeof c === 'string')) { return Buffer.from(accum.join('')) } return Buffer.concat(accum, accumBytes) } catch (error) { throw new FetchError( `Could not create Buffer from response body for ${data.url}: ${error.message}`, 'system', error ) } } else { throw new FetchError( `Premature close of server response while trying to fetch ${data.url}` ) } } /** * Clone body given Res/Req instance * * @param Mixed instance Response or Request instance * @param String highWaterMark highWaterMark for both PassThrough body streams * @return Mixed */ const clone = (instance, highWaterMark) => { let p1 let p2 let { body } = instance[INTERNALS$2] // Don't allow cloning a used body if (instance.bodyUsed) { throw new Error('cannot clone body after it is used') } // Check that body is a stream and not form-data object // note: we can't clone the form-data object without having it as a dependency if (body instanceof Stream && typeof body.getBoundary !== 'function') { // Tee instance body p1 = new PassThrough({ highWaterMark }) p2 = new PassThrough({ highWaterMark }) body.pipe(p1) body.pipe(p2) // Set instance body to teed body and return the other teed body instance[INTERNALS$2].stream = p1 body = p2 } return body } const getNonSpecFormDataBoundary = deprecate( (body) => body.getBoundary(), "form-data doesn't follow the spec and requires special treatment. Use alternative package", 'https://github.com/node-fetch/node-fetch/issues/1167' ) /** * Performs the operation "extract a `Content-Type` value from |object|" as * specified in the specification: * https://fetch.spec.whatwg.org/#concept-bodyinit-extract * * This function assumes that instance.body is present. * * @param {any} body Any options.body input * @returns {string | null} */ const extractContentType = (body, request) => { // Body is null or undefined if (body === null) { return null } // Body is string if (typeof body === 'string') { return 'text/plain;charset=UTF-8' } // Body is a URLSearchParams if (isURLSearchParameters(body)) { return 'application/x-www-form-urlencoded;charset=UTF-8' } // Body is blob if (isBlob(body)) { return body.type || null } // Body is a Buffer (Buffer, ArrayBuffer or ArrayBufferView) if ( Buffer.isBuffer(body) || types.isAnyArrayBuffer(body) || ArrayBuffer.isView(body) ) { return null } if (body instanceof FormData) { return `multipart/form-data; boundary=${request[INTERNALS$2].boundary}` } // Detect form data input from form-data module if (body && typeof body.getBoundary === 'function') { return `multipart/form-data;boundary=${getNonSpecFormDataBoundary(body)}` } // Body is stream - can't really do much about this if (body instanceof Stream) { return null } // Body constructor defaults other things to string return 'text/plain;charset=UTF-8' } /** * The Fetch Standard treats this as if "total bytes" is a property on the body. * For us, we have to explicitly get it with a function. * * ref: https://fetch.spec.whatwg.org/#concept-body-total-bytes * * @param {any} obj.body Body object from the Body instance. * @returns {number | null} */ const getTotalBytes = (request) => { const { body } = request[INTERNALS$2] // Body is null or undefined if (body === null) { return 0 } // Body is Blob if (isBlob(body)) { return body.size } // Body is Buffer if (Buffer.isBuffer(body)) { return body.length } // Detect form data input from form-data module if (body && typeof body.getLengthSync === 'function') { return body.hasKnownLength && body.hasKnownLength() ? body.getLengthSync() : null } // Body is stream return null } /** * Write a Body to a Node.js WritableStream (e.g. http.Request) object. * * @param {Stream.Writable} dest The stream to write to. * @param obj.body Body object from the Body instance. * @returns {Promise} */ const writeToStream = async (dest, { body }) => { if (body === null) { // Body is null dest.end() } else { // Body is stream await pipeline(body, dest) } } /** * Headers.js * * Headers class offers convenient helpers */ /* c8 ignore next 9 */ const validateHeaderName = typeof http.validateHeaderName === 'function' ? http.validateHeaderName : (name) => { if (!/^[\^`\-\w!#$%&'*+.|~]+$/.test(name)) { const error = new TypeError( `Header name must be a valid HTTP token [${name}]` ) Object.defineProperty(error, 'code', { value: 'ERR_INVALID_HTTP_TOKEN', }) throw error } } /* c8 ignore next 9 */ const validateHeaderValue = typeof http.validateHeaderValue === 'function' ? http.validateHeaderValue : (name, value) => { if (/[^\t\u0020-\u007E\u0080-\u00FF]/.test(value)) { const error = new TypeError( `Invalid character in header content ["${name}"]` ) Object.defineProperty(error, 'code', { value: 'ERR_INVALID_CHAR' }) throw error } } /** * @typedef {Headers | Record | Iterable | Iterable>} HeadersInit */ /** * This Fetch API interface allows you to perform various actions on HTTP request and response headers. * These actions include retrieving, setting, adding to, and removing. * A Headers object has an associated header list, which is initially empty and consists of zero or more name and value pairs. * You can add to this using methods like append() (see Examples.) * In all methods of this interface, header names are matched by case-insensitive byte sequence. * */ class Headers extends URLSearchParams { /** * Headers class * * @constructor * @param {HeadersInit} [init] - Response headers */ constructor(init) { // Validate and normalize init object in [name, value(s)][] /** @type {string[][]} */ let result = [] if (init instanceof Headers) { const raw = init.raw() for (const [name, values] of Object.entries(raw)) { result.push(...values.map((value) => [name, value])) } } else if (init == null); else if (typeof init === 'object' && !types.isBoxedPrimitive(init)) { const method = init[Symbol.iterator] // eslint-disable-next-line no-eq-null, eqeqeq if (method == null) { // Record result.push(...Object.entries(init)) } else { if (typeof method !== 'function') { throw new TypeError('Header pairs must be iterable') } // Sequence> // Note: per spec we have to first exhaust the lists then process them result = [...init] .map((pair) => { if (typeof pair !== 'object' || types.isBoxedPrimitive(pair)) { throw new TypeError('Each header pair must be an iterable object') } return [...pair] }) .map((pair) => { if (pair.length !== 2) { throw new TypeError('Each header pair must be a name/value tuple') } return [...pair] }) } } else { throw new TypeError( "Failed to construct 'Headers': The provided value is not of type '(sequence> or record)" ) } // Validate and lowercase result = result.length > 0 ? result.map(([name, value]) => { validateHeaderName(name) validateHeaderValue(name, String(value)) return [String(name).toLowerCase(), String(value)] }) : undefined super(result) // Returning a Proxy that will lowercase key names, validate parameters and sort keys // eslint-disable-next-line no-constructor-return return new Proxy(this, { get(target, p, receiver) { switch (p) { case 'append': case 'set': return (name, value) => { validateHeaderName(name) validateHeaderValue(name, String(value)) return URLSearchParams.prototype[p].call( target, String(name).toLowerCase(), String(value) ) } case 'delete': case 'has': case 'getAll': return (name) => { validateHeaderName(name) return URLSearchParams.prototype[p].call( target, String(name).toLowerCase() ) } case 'keys': return () => { target.sort() return new Set(URLSearchParams.prototype.keys.call(target)).keys() } default: return Reflect.get(target, p, receiver) } }, }) /* c8 ignore next */ } get [Symbol.toStringTag]() { return this.constructor.name } toString() { return Object.prototype.toString.call(this) } get(name) { const values = this.getAll(name) if (values.length === 0) { return null } let value = values.join(', ') if (/^content-encoding$/i.test(name)) { value = value.toLowerCase() } return value } forEach(callback, thisArg = undefined) { for (const name of this.keys()) { Reflect.apply(callback, thisArg, [this.get(name), name, this]) } } *values() { for (const name of this.keys()) { yield this.get(name) } } /** * @type {() => IterableIterator<[string, string]>} */ *entries() { for (const name of this.keys()) { yield [name, this.get(name)] } } [Symbol.iterator]() { return this.entries() } /** * Node-fetch non-spec method * returning all headers and their values as array * @returns {Record} */ raw() { return [...this.keys()].reduce((result, key) => { result[key] = this.getAll(key) return result }, {}) } /** * For better console.log(headers) and also to convert Headers into Node.js Request compatible format */ [Symbol.for('nodejs.util.inspect.custom')]() { return [...this.keys()].reduce((result, key) => { const values = this.getAll(key) // Http.request() only supports string as Host header. // This hack makes specifying custom Host header possible. if (key === 'host') { result[key] = values[0] } else { result[key] = values.length > 1 ? values : values[0] } return result }, {}) } } /** * Re-shaping object for Web IDL tests * Only need to do it for overridden methods */ Object.defineProperties( Headers.prototype, ['get', 'entries', 'forEach', 'values'].reduce((result, property) => { result[property] = { enumerable: true } return result }, {}) ) /** * Create a Headers object from an http.IncomingMessage.rawHeaders, ignoring those that do * not conform to HTTP grammar productions. * @param {import('http').IncomingMessage['rawHeaders']} headers */ function fromRawHeaders(headers = []) { return new Headers( headers // Split into pairs .reduce((result, value, index, array) => { if (index % 2 === 0) { result.push(array.slice(index, index + 2)) } return result }, []) .filter(([name, value]) => { try { validateHeaderName(name) validateHeaderValue(name, String(value)) return true } catch { return false } }) ) } const redirectStatus = new Set([301, 302, 303, 307, 308]) /** * Redirect code matching * * @param {number} code - Status code * @return {boolean} */ const isRedirect = (code) => { return redirectStatus.has(code) } /** * Response.js * * Response class provides content decoding */ const INTERNALS$1 = Symbol('Response internals') /** * Response class * * Ref: https://fetch.spec.whatwg.org/#response-class * * @param Stream body Readable stream * @param Object opts Response options * @return Void */ class Response extends Body { constructor(body = null, options = {}) { super(body, options) // eslint-disable-next-line no-eq-null, eqeqeq, no-negated-condition const status = options.status != null ? options.status : 200 const headers = new Headers(options.headers) if (body !== null && !headers.has('Content-Type')) { const contentType = extractContentType(body, this) if (contentType) { headers.append('Content-Type', contentType) } } this[INTERNALS$1] = { type: 'default', url: options.url, status, statusText: options.statusText || '', headers, counter: options.counter, highWaterMark: options.highWaterMark, } } get type() { return this[INTERNALS$1].type } get url() { return this[INTERNALS$1].url || '' } get status() { return this[INTERNALS$1].status } /** * Convenience property representing if the request ended normally */ get ok() { return this[INTERNALS$1].status >= 200 && this[INTERNALS$1].status < 300 } get redirected() { return this[INTERNALS$1].counter > 0 } get statusText() { return this[INTERNALS$1].statusText } get headers() { return this[INTERNALS$1].headers } get highWaterMark() { return this[INTERNALS$1].highWaterMark } /** * Clone this response * * @return Response */ clone() { return new Response(clone(this, this.highWaterMark), { type: this.type, url: this.url, status: this.status, statusText: this.statusText, headers: this.headers, ok: this.ok, redirected: this.redirected, size: this.size, highWaterMark: this.highWaterMark, }) } /** * @param {string} url The URL that the new response is to originate from. * @param {number} status An optional status code for the response (e.g., 302.) * @returns {Response} A Response object. */ static redirect(url, status = 302) { if (!isRedirect(status)) { throw new RangeError( 'Failed to execute "redirect" on "response": Invalid status code' ) } return new Response(null, { headers: { location: new URL(url).toString(), }, status, }) } static error() { const response = new Response(null, { status: 0, statusText: '' }) response[INTERNALS$1].type = 'error' return response } get [Symbol.toStringTag]() { return 'Response' } } Object.defineProperties(Response.prototype, { type: { enumerable: true }, url: { enumerable: true }, status: { enumerable: true }, ok: { enumerable: true }, redirected: { enumerable: true }, statusText: { enumerable: true }, headers: { enumerable: true }, clone: { enumerable: true }, }) const getSearch = (parsedURL) => { if (parsedURL.search) { return parsedURL.search } const lastOffset = parsedURL.href.length - 1 const hash = parsedURL.hash || (parsedURL.href[lastOffset] === '#' ? '#' : '') return parsedURL.href[lastOffset - hash.length] === '?' ? '?' : '' } /** * @external URL * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/URL|URL} */ /** * @module utils/referrer * @private */ /** * @see {@link https://w3c.github.io/webappsec-referrer-policy/#strip-url|Referrer Policy §8.4. Strip url for use as a referrer} * @param {string} URL * @param {boolean} [originOnly=false] */ function stripURLForUseAsAReferrer(url, originOnly = false) { // 1. If url is null, return no referrer. if (url == null) { // eslint-disable-line no-eq-null, eqeqeq return 'no-referrer' } url = new URL(url) // 2. If url's scheme is a local scheme, then return no referrer. if (/^(about|blob|data):$/.test(url.protocol)) { return 'no-referrer' } // 3. Set url's username to the empty string. url.username = '' // 4. Set url's password to null. // Note: `null` appears to be a mistake as this actually results in the password being `"null"`. url.password = '' // 5. Set url's fragment to null. // Note: `null` appears to be a mistake as this actually results in the fragment being `"#null"`. url.hash = '' // 6. If the origin-only flag is true, then: if (originOnly) { // 6.1. Set url's path to null. // Note: `null` appears to be a mistake as this actually results in the path being `"/null"`. url.pathname = '' // 6.2. Set url's query to null. // Note: `null` appears to be a mistake as this actually results in the query being `"?null"`. url.search = '' } // 7. Return url. return url } /** * @see {@link https://w3c.github.io/webappsec-referrer-policy/#enumdef-referrerpolicy|enum ReferrerPolicy} */ const ReferrerPolicy = new Set([ '', 'no-referrer', 'no-referrer-when-downgrade', 'same-origin', 'origin', 'strict-origin', 'origin-when-cross-origin', 'strict-origin-when-cross-origin', 'unsafe-url', ]) /** * @see {@link https://w3c.github.io/webappsec-referrer-policy/#default-referrer-policy|default referrer policy} */ const DEFAULT_REFERRER_POLICY = 'strict-origin-when-cross-origin' /** * @see {@link https://w3c.github.io/webappsec-referrer-policy/#referrer-policies|Referrer Policy §3. Referrer Policies} * @param {string} referrerPolicy * @returns {string} referrerPolicy */ function validateReferrerPolicy(referrerPolicy) { if (!ReferrerPolicy.has(referrerPolicy)) { throw new TypeError(`Invalid referrerPolicy: ${referrerPolicy}`) } return referrerPolicy } /** * @see {@link https://w3c.github.io/webappsec-secure-contexts/#is-origin-trustworthy|Referrer Policy §3.2. Is origin potentially trustworthy?} * @param {external:URL} url * @returns `true`: "Potentially Trustworthy", `false`: "Not Trustworthy" */ function isOriginPotentiallyTrustworthy(url) { // 1. If origin is an opaque origin, return "Not Trustworthy". // Not applicable // 2. Assert: origin is a tuple origin. // Not for implementations // 3. If origin's scheme is either "https" or "wss", return "Potentially Trustworthy". if (/^(http|ws)s:$/.test(url.protocol)) { return true } // 4. If origin's host component matches one of the CIDR notations 127.0.0.0/8 or ::1/128 [RFC4632], return "Potentially Trustworthy". const hostIp = url.host.replace(/(^\[)|(]$)/g, '') const hostIPVersion = isIP(hostIp) if (hostIPVersion === 4 && /^127\./.test(hostIp)) { return true } if (hostIPVersion === 6 && /^(((0+:){7})|(::(0+:){0,6}))0*1$/.test(hostIp)) { return true } // 5. If origin's host component is "localhost" or falls within ".localhost", and the user agent conforms to the name resolution rules in [let-localhost-be-localhost], return "Potentially Trustworthy". // We are returning FALSE here because we cannot ensure conformance to // let-localhost-be-loalhost (https://tools.ietf.org/html/draft-west-let-localhost-be-localhost) if (/^(.+\.)*localhost$/.test(url.host)) { return false } // 6. If origin's scheme component is file, return "Potentially Trustworthy". if (url.protocol === 'file:') { return true } // 7. If origin's scheme component is one which the user agent considers to be authenticated, return "Potentially Trustworthy". // Not supported // 8. If origin has been configured as a trustworthy origin, return "Potentially Trustworthy". // Not supported // 9. Return "Not Trustworthy". return false } /** * @see {@link https://w3c.github.io/webappsec-secure-contexts/#is-url-trustworthy|Referrer Policy §3.3. Is url potentially trustworthy?} * @param {external:URL} url * @returns `true`: "Potentially Trustworthy", `false`: "Not Trustworthy" */ function isUrlPotentiallyTrustworthy(url) { // 1. If url is "about:blank" or "about:srcdoc", return "Potentially Trustworthy". if (/^about:(blank|srcdoc)$/.test(url)) { return true } // 2. If url's scheme is "data", return "Potentially Trustworthy". if (url.protocol === 'data:') { return true } // Note: The origin of blob: and filesystem: URLs is the origin of the context in which they were // created. Therefore, blobs created in a trustworthy origin will themselves be potentially // trustworthy. if (/^(blob|filesystem):$/.test(url.protocol)) { return true } // 3. Return the result of executing §3.2 Is origin potentially trustworthy? on url's origin. return isOriginPotentiallyTrustworthy(url) } /** * Modifies the referrerURL to enforce any extra security policy considerations. * @see {@link https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer|Referrer Policy §8.3. Determine request's Referrer}, step 7 * @callback module:utils/referrer~referrerURLCallback * @param {external:URL} referrerURL * @returns {external:URL} modified referrerURL */ /** * Modifies the referrerOrigin to enforce any extra security policy considerations. * @see {@link https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer|Referrer Policy §8.3. Determine request's Referrer}, step 7 * @callback module:utils/referrer~referrerOriginCallback * @param {external:URL} referrerOrigin * @returns {external:URL} modified referrerOrigin */ /** * @see {@link https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer|Referrer Policy §8.3. Determine request's Referrer} * @param {Request} request * @param {object} o * @param {module:utils/referrer~referrerURLCallback} o.referrerURLCallback * @param {module:utils/referrer~referrerOriginCallback} o.referrerOriginCallback * @returns {external:URL} Request's referrer */ function determineRequestsReferrer( request, { referrerURLCallback, referrerOriginCallback } = {} ) { // There are 2 notes in the specification about invalid pre-conditions. We return null, here, for // these cases: // > Note: If request's referrer is "no-referrer", Fetch will not call into this algorithm. // > Note: If request's referrer policy is the empty string, Fetch will not call into this // > algorithm. if (request.referrer === 'no-referrer' || request.referrerPolicy === '') { return null } // 1. Let policy be request's associated referrer policy. const policy = request.referrerPolicy // 2. Let environment be request's client. // not applicable to node.js // 3. Switch on request's referrer: if (request.referrer === 'about:client') { return 'no-referrer' } // "a URL": Let referrerSource be request's referrer. const referrerSource = request.referrer // 4. Let request's referrerURL be the result of stripping referrerSource for use as a referrer. let referrerURL = stripURLForUseAsAReferrer(referrerSource) // 5. Let referrerOrigin be the result of stripping referrerSource for use as a referrer, with the // origin-only flag set to true. let referrerOrigin = stripURLForUseAsAReferrer(referrerSource, true) // 6. If the result of serializing referrerURL is a string whose length is greater than 4096, set // referrerURL to referrerOrigin. if (referrerURL.toString().length > 4096) { referrerURL = referrerOrigin } // 7. The user agent MAY alter referrerURL or referrerOrigin at this point to enforce arbitrary // policy considerations in the interests of minimizing data leakage. For example, the user // agent could strip the URL down to an origin, modify its host, replace it with an empty // string, etc. if (referrerURLCallback) { referrerURL = referrerURLCallback(referrerURL) } if (referrerOriginCallback) { referrerOrigin = referrerOriginCallback(referrerOrigin) } // 8.Execute the statements corresponding to the value of policy: const currentURL = new URL(request.url) switch (policy) { case 'no-referrer': return 'no-referrer' case 'origin': return referrerOrigin case 'unsafe-url': return referrerURL case 'strict-origin': // 1. If referrerURL is a potentially trustworthy URL and request's current URL is not a // potentially trustworthy URL, then return no referrer. if ( isUrlPotentiallyTrustworthy(referrerURL) && !isUrlPotentiallyTrustworthy(currentURL) ) { return 'no-referrer' } // 2. Return referrerOrigin. return referrerOrigin.toString() case 'strict-origin-when-cross-origin': // 1. If the origin of referrerURL and the origin of request's current URL are the same, then // return referrerURL. if (referrerURL.origin === currentURL.origin) { return referrerURL } // 2. If referrerURL is a potentially trustworthy URL and request's current URL is not a // potentially trustworthy URL, then return no referrer. if ( isUrlPotentiallyTrustworthy(referrerURL) && !isUrlPotentiallyTrustworthy(currentURL) ) { return 'no-referrer' } // 3. Return referrerOrigin. return referrerOrigin case 'same-origin': // 1. If the origin of referrerURL and the origin of request's current URL are the same, then // return referrerURL. if (referrerURL.origin === currentURL.origin) { return referrerURL } // 2. Return no referrer. return 'no-referrer' case 'origin-when-cross-origin': // 1. If the origin of referrerURL and the origin of request's current URL are the same, then // return referrerURL. if (referrerURL.origin === currentURL.origin) { return referrerURL } // Return referrerOrigin. return referrerOrigin case 'no-referrer-when-downgrade': // 1. If referrerURL is a potentially trustworthy URL and request's current URL is not a // potentially trustworthy URL, then return no referrer. if ( isUrlPotentiallyTrustworthy(referrerURL) && !isUrlPotentiallyTrustworthy(currentURL) ) { return 'no-referrer' } // 2. Return referrerURL. return referrerURL default: throw new TypeError(`Invalid referrerPolicy: ${policy}`) } } /** * @see {@link https://w3c.github.io/webappsec-referrer-policy/#parse-referrer-policy-from-header|Referrer Policy §8.1. Parse a referrer policy from a Referrer-Policy header} * @param {Headers} headers Response headers * @returns {string} policy */ function parseReferrerPolicyFromHeader(headers) { // 1. Let policy-tokens be the result of extracting header list values given `Referrer-Policy` // and response’s header list. const policyTokens = (headers.get('referrer-policy') || '').split(/[,\s]+/) // 2. Let policy be the empty string. let policy = '' // 3. For each token in policy-tokens, if token is a referrer policy and token is not the empty // string, then set policy to token. // Note: This algorithm loops over multiple policy values to allow deployment of new policy // values with fallbacks for older user agents, as described in § 11.1 Unknown Policy Values. for (const token of policyTokens) { if (token && ReferrerPolicy.has(token)) { policy = token } } // 4. Return policy. return policy } /** * Request.js * * Request class contains server only options * * All spec algorithm step numbers are based on https://fetch.spec.whatwg.org/commit-snapshots/ae716822cb3a61843226cd090eefc6589446c1d2/. */ const INTERNALS = Symbol('Request internals') /** * Check if `obj` is an instance of Request. * * @param {*} object * @return {boolean} */ const isRequest = (object) => { return typeof object === 'object' && typeof object[INTERNALS] === 'object' } const doBadDataWarn = deprecate( () => {}, '.data is not a valid RequestInit property, use .body instead', 'https://github.com/node-fetch/node-fetch/issues/1000 (request)' ) /** * Request class * * Ref: https://fetch.spec.whatwg.org/#request-class * * @param Mixed input Url or Request instance * @param Object init Custom options * @return Void */ class Request extends Body { constructor(input, init = {}) { let parsedURL // Normalize input and force URL to be encoded as UTF-8 (https://github.com/node-fetch/node-fetch/issues/245) if (isRequest(input)) { parsedURL = new URL(input.url) } else { parsedURL = new URL(input) input = {} } if (parsedURL.username !== '' || parsedURL.password !== '') { throw new TypeError(`${parsedURL} is an url with embedded credentials.`) } let method = init.method || input.method || 'GET' method = method.toUpperCase() if ('data' in init) { doBadDataWarn() } // eslint-disable-next-line no-eq-null, eqeqeq if ( (init.body != null || (isRequest(input) && input.body !== null)) && (method === 'GET' || method === 'HEAD') ) { throw new TypeError('Request with GET/HEAD method cannot have body') } const inputBody = init.body ? init.body : isRequest(input) && input.body !== null ? clone(input) : null super(inputBody, { size: init.size || input.size || 0, }) const headers = new Headers(init.headers || input.headers || {}) if (inputBody !== null && !headers.has('Content-Type')) { const contentType = extractContentType(inputBody, this) if (contentType) { headers.set('Content-Type', contentType) } } let signal = isRequest(input) ? input.signal : null if ('signal' in init) { signal = init.signal } // eslint-disable-next-line no-eq-null, eqeqeq if (signal != null && !isAbortSignal(signal)) { throw new TypeError( 'Expected signal to be an instanceof AbortSignal or EventTarget' ) } // §5.4, Request constructor steps, step 15.1 // eslint-disable-next-line no-eq-null, eqeqeq let referrer = init.referrer == null ? input.referrer : init.referrer if (referrer === '') { // §5.4, Request constructor steps, step 15.2 referrer = 'no-referrer' } else if (referrer) { // §5.4, Request constructor steps, step 15.3.1, 15.3.2 const parsedReferrer = new URL(referrer) // §5.4, Request constructor steps, step 15.3.3, 15.3.4 referrer = /^about:(\/\/)?client$/.test(parsedReferrer) ? 'client' : parsedReferrer } else { referrer = undefined } this[INTERNALS] = { method, redirect: init.redirect || input.redirect || 'follow', headers, parsedURL, signal, referrer, } // Node-fetch-only options this.follow = init.follow === undefined ? input.follow === undefined ? 20 : input.follow : init.follow this.compress = init.compress === undefined ? input.compress === undefined ? true : input.compress : init.compress this.counter = init.counter || input.counter || 0 this.agent = init.agent || input.agent this.highWaterMark = init.highWaterMark || input.highWaterMark || 16384 this.insecureHTTPParser = init.insecureHTTPParser || input.insecureHTTPParser || false // §5.4, Request constructor steps, step 16. // Default is empty string per https://fetch.spec.whatwg.org/#concept-request-referrer-policy this.referrerPolicy = init.referrerPolicy || input.referrerPolicy || '' } /** @returns {string} */ get method() { return this[INTERNALS].method } /** @returns {string} */ get url() { return format$1(this[INTERNALS].parsedURL) } /** @returns {Headers} */ get headers() { return this[INTERNALS].headers } get redirect() { return this[INTERNALS].redirect } /** @returns {AbortSignal} */ get signal() { return this[INTERNALS].signal } // https://fetch.spec.whatwg.org/#dom-request-referrer get referrer() { if (this[INTERNALS].referrer === 'no-referrer') { return '' } if (this[INTERNALS].referrer === 'client') { return 'about:client' } if (this[INTERNALS].referrer) { return this[INTERNALS].referrer.toString() } return undefined } get referrerPolicy() { return this[INTERNALS].referrerPolicy } set referrerPolicy(referrerPolicy) { this[INTERNALS].referrerPolicy = validateReferrerPolicy(referrerPolicy) } /** * Clone this request * * @return Request */ clone() { return new Request(this) } get [Symbol.toStringTag]() { return 'Request' } } Object.defineProperties(Request.prototype, { method: { enumerable: true }, url: { enumerable: true }, headers: { enumerable: true }, redirect: { enumerable: true }, clone: { enumerable: true }, signal: { enumerable: true }, referrer: { enumerable: true }, referrerPolicy: { enumerable: true }, }) /** * Convert a Request to Node.js http request options. * * @param {Request} request - A Request instance * @return The options object to be passed to http.request */ const getNodeRequestOptions = (request) => { const { parsedURL } = request[INTERNALS] const headers = new Headers(request[INTERNALS].headers) // Fetch step 1.3 if (!headers.has('Accept')) { headers.set('Accept', '*/*') } // HTTP-network-or-cache fetch steps 2.4-2.7 let contentLengthValue = null if (request.body === null && /^(post|put)$/i.test(request.method)) { contentLengthValue = '0' } if (request.body !== null) { const totalBytes = getTotalBytes(request) // Set Content-Length if totalBytes is a number (that is not NaN) if (typeof totalBytes === 'number' && !Number.isNaN(totalBytes)) { contentLengthValue = String(totalBytes) } } if (contentLengthValue) { headers.set('Content-Length', contentLengthValue) } // 4.1. Main fetch, step 2.6 // > If request's referrer policy is the empty string, then set request's referrer policy to the // > default referrer policy. if (request.referrerPolicy === '') { request.referrerPolicy = DEFAULT_REFERRER_POLICY } // 4.1. Main fetch, step 2.7 // > If request's referrer is not "no-referrer", set request's referrer to the result of invoking // > determine request's referrer. if (request.referrer && request.referrer !== 'no-referrer') { request[INTERNALS].referrer = determineRequestsReferrer(request) } else { request[INTERNALS].referrer = 'no-referrer' } // 4.5. HTTP-network-or-cache fetch, step 6.9 // > If httpRequest's referrer is a URL, then append `Referer`/httpRequest's referrer, serialized // > and isomorphic encoded, to httpRequest's header list. if (request[INTERNALS].referrer instanceof URL) { headers.set('Referer', request.referrer) } // HTTP-network-or-cache fetch step 2.11 if (!headers.has('User-Agent')) { headers.set('User-Agent', 'node-fetch') } // HTTP-network-or-cache fetch step 2.15 if (request.compress && !headers.has('Accept-Encoding')) { headers.set('Accept-Encoding', 'gzip,deflate,br') } let { agent } = request if (typeof agent === 'function') { agent = agent(parsedURL) } if (!headers.has('Connection') && !agent) { headers.set('Connection', 'close') } // HTTP-network fetch step 4.2 // chunked encoding is handled by Node.js const search = getSearch(parsedURL) // Pass the full URL directly to request(), but overwrite the following // options: const options = { // Overwrite search to retain trailing ? (issue #776) path: parsedURL.pathname + search, // The following options are not expressed in the URL method: request.method, headers: headers[Symbol.for('nodejs.util.inspect.custom')](), insecureHTTPParser: request.insecureHTTPParser, agent, } return { /** @type {URL} */ parsedURL, options, } } /** * AbortError interface for cancelled requests */ class AbortError extends FetchBaseError { constructor(message, type = 'aborted') { super(message, type) } } /** * Index.js * * a request API compatible with window.fetch * * All spec algorithm step numbers are based on https://fetch.spec.whatwg.org/commit-snapshots/ae716822cb3a61843226cd090eefc6589446c1d2/. */ const supportedSchemas = new Set(['data:', 'http:', 'https:']) /** * Fetch function * * @param {string | URL | import('./request').default} url - Absolute url or Request instance * @param {*} [options_] - Fetch options * @return {Promise} */ async function fetch$1(url, options_) { return new Promise((resolve, reject) => { // Build request object const request = new Request(url, options_) const { parsedURL, options } = getNodeRequestOptions(request) if (!supportedSchemas.has(parsedURL.protocol)) { throw new TypeError( `node-fetch cannot load ${url}. URL scheme "${parsedURL.protocol.replace( /:$/, '' )}" is not supported.` ) } if (parsedURL.protocol === 'data:') { const data = dataUriToBuffer(request.url) const response = new Response(data, { headers: { 'Content-Type': data.typeFull }, }) resolve(response) return } // Wrap http.request into fetch const send = (parsedURL.protocol === 'https:' ? https : http).request const { signal } = request let response = null const abort = () => { const error = new AbortError('The operation was aborted.') reject(error) if (request.body && request.body instanceof Stream.Readable) { request.body.destroy(error) } if (!response || !response.body) { return } response.body.emit('error', error) } if (signal && signal.aborted) { abort() return } const abortAndFinalize = () => { abort() finalize() } // Send request const request_ = send(parsedURL.toString(), options) if (signal) { signal.addEventListener('abort', abortAndFinalize) } const finalize = () => { request_.abort() if (signal) { signal.removeEventListener('abort', abortAndFinalize) } } request_.on('error', (error) => { reject( new FetchError( `request to ${request.url} failed, reason: ${error.message}`, 'system', error ) ) finalize() }) fixResponseChunkedTransferBadEnding(request_, (error) => { response.body.destroy(error) }) /* c8 ignore next 18 */ if (process.version < 'v14') { // Before Node.js 14, pipeline() does not fully support async iterators and does not always // properly handle when the socket close/end events are out of order. request_.on('socket', (s) => { let endedWithEventsCount s.prependListener('end', () => { endedWithEventsCount = s._eventsCount }) s.prependListener('close', (hadError) => { // if end happened before close but the socket didn't emit an error, do it now if (response && endedWithEventsCount < s._eventsCount && !hadError) { const error = new Error('Premature close') error.code = 'ERR_STREAM_PREMATURE_CLOSE' response.body.emit('error', error) } }) }) } request_.on('response', (response_) => { request_.setTimeout(0) const headers = fromRawHeaders(response_.rawHeaders) // HTTP fetch step 5 if (isRedirect(response_.statusCode)) { // HTTP fetch step 5.2 const location = headers.get('Location') // HTTP fetch step 5.3 let locationURL = null try { locationURL = location === null ? null : new URL(location, request.url) } catch { // error here can only be invalid URL in Location: header // do not throw when options.redirect == manual // let the user extract the errorneous redirect URL if (request.redirect !== 'manual') { reject( new FetchError( `uri requested responds with an invalid redirect URL: ${location}`, 'invalid-redirect' ) ) finalize() return } } // HTTP fetch step 5.5 switch (request.redirect) { case 'error': reject( new FetchError( `uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect' ) ) finalize() return case 'manual': // Nothing to do break case 'follow': { // HTTP-redirect fetch step 2 if (locationURL === null) { break } // HTTP-redirect fetch step 5 if (request.counter >= request.follow) { reject( new FetchError( `maximum redirect reached at: ${request.url}`, 'max-redirect' ) ) finalize() return } // HTTP-redirect fetch step 6 (counter increment) // Create a new Request object. const requestOptions = { headers: new Headers(request.headers), follow: request.follow, counter: request.counter + 1, agent: request.agent, compress: request.compress, method: request.method, body: clone(request), signal: request.signal, size: request.size, referrer: request.referrer, referrerPolicy: request.referrerPolicy, } // when forwarding sensitive headers like "Authorization", // "WWW-Authenticate", and "Cookie" to untrusted targets, // headers will be ignored when following a redirect to a domain // that is not a subdomain match or exact match of the initial domain. // For example, a redirect from "foo.com" to either "foo.com" or "sub.foo.com" // will forward the sensitive headers, but a redirect to "bar.com" will not. if (!isDomainOrSubdomain(request.url, locationURL)) { for (const name of [ 'authorization', 'www-authenticate', 'cookie', 'cookie2', ]) { requestOptions.headers.delete(name) } } // HTTP-redirect fetch step 9 if ( response_.statusCode !== 303 && request.body && options_.body instanceof Stream.Readable ) { reject( new FetchError( 'Cannot follow redirect with body being a readable stream', 'unsupported-redirect' ) ) finalize() return } // HTTP-redirect fetch step 11 if ( response_.statusCode === 303 || ((response_.statusCode === 301 || response_.statusCode === 302) && request.method === 'POST') ) { requestOptions.method = 'GET' requestOptions.body = undefined requestOptions.headers.delete('content-length') } // HTTP-redirect fetch step 14 const responseReferrerPolicy = parseReferrerPolicyFromHeader(headers) if (responseReferrerPolicy) { requestOptions.referrerPolicy = responseReferrerPolicy } // HTTP-redirect fetch step 15 resolve(fetch$1(new Request(locationURL, requestOptions))) finalize() return } default: return reject( new TypeError( `Redirect option '${request.redirect}' is not a valid value of RequestRedirect` ) ) } } // Prepare response if (signal) { response_.once('end', () => { signal.removeEventListener('abort', abortAndFinalize) }) } let body = pipeline$1(response_, new PassThrough(), (error) => { if (error) { reject(error) } }) // see https://github.com/nodejs/node/pull/29376 /* c8 ignore next 3 */ if (process.version < 'v12.10') { response_.on('aborted', abortAndFinalize) } const responseOptions = { url: request.url, status: response_.statusCode, statusText: response_.statusMessage, headers, size: request.size, counter: request.counter, highWaterMark: request.highWaterMark, } // HTTP-network fetch step 12.1.1.3 const codings = headers.get('Content-Encoding') // HTTP-network fetch step 12.1.1.4: handle content codings // in following scenarios we ignore compression support // 1. compression support is disabled // 2. HEAD request // 3. no Content-Encoding header // 4. no content response (204) // 5. content not modified response (304) if ( !request.compress || request.method === 'HEAD' || codings === null || response_.statusCode === 204 || response_.statusCode === 304 ) { response = new Response(body, responseOptions) resolve(response) return } // For Node v6+ // Be less strict when decoding compressed responses, since sometimes // servers send slightly invalid responses that are still accepted // by common browsers. // Always using Z_SYNC_FLUSH is what cURL does. const zlibOptions = { flush: zlib.Z_SYNC_FLUSH, finishFlush: zlib.Z_SYNC_FLUSH, } // For gzip if (codings === 'gzip' || codings === 'x-gzip') { body = pipeline$1(body, zlib.createGunzip(zlibOptions), (error) => { if (error) { reject(error) } }) response = new Response(body, responseOptions) resolve(response) return } // For deflate if (codings === 'deflate' || codings === 'x-deflate') { // Handle the infamous raw deflate response from old servers // a hack for old IIS and Apache servers const raw = pipeline$1(response_, new PassThrough(), (error) => { if (error) { reject(error) } }) raw.once('data', (chunk) => { // See http://stackoverflow.com/questions/37519828 if ((chunk[0] & 0x0f) === 0x08) { body = pipeline$1(body, zlib.createInflate(), (error) => { if (error) { reject(error) } }) } else { body = pipeline$1(body, zlib.createInflateRaw(), (error) => { if (error) { reject(error) } }) } response = new Response(body, responseOptions) resolve(response) }) raw.once('end', () => { // Some old IIS servers return zero-length OK deflate responses, so // 'data' is never emitted. See https://github.com/node-fetch/node-fetch/pull/903 if (!response) { response = new Response(body, responseOptions) resolve(response) } }) return } // For br if (codings === 'br') { body = pipeline$1(body, zlib.createBrotliDecompress(), (error) => { if (error) { reject(error) } }) response = new Response(body, responseOptions) resolve(response) return } // Otherwise, use response as-is response = new Response(body, responseOptions) resolve(response) }) // eslint-disable-next-line promise/prefer-await-to-then writeToStream(request_, request).catch(reject) }) } function fixResponseChunkedTransferBadEnding(request, errorCallback) { const LAST_CHUNK = Buffer.from('0\r\n\r\n') let isChunkedTransfer = false let properLastChunkReceived = false let previousChunk request.on('response', (response) => { const { headers } = response isChunkedTransfer = headers['transfer-encoding'] === 'chunked' && !headers['content-length'] }) request.on('socket', (socket) => { const onSocketClose = () => { if (isChunkedTransfer && !properLastChunkReceived) { const error = new Error('Premature close') error.code = 'ERR_STREAM_PREMATURE_CLOSE' errorCallback(error) } } socket.prependListener('close', onSocketClose) request.on('abort', () => { socket.removeListener('close', onSocketClose) }) socket.on('data', (buf) => { properLastChunkReceived = Buffer.compare(buf.slice(-5), LAST_CHUNK) === 0 // Sometimes final 0-length chunk and end of message code are in separate packets if (!properLastChunkReceived && previousChunk) { properLastChunkReceived = Buffer.compare(previousChunk.slice(-3), LAST_CHUNK.slice(0, 3)) === 0 && Buffer.compare(buf.slice(-2), LAST_CHUNK.slice(3)) === 0 } previousChunk = buf }) }) } const fetch = { fetch(resource, init) { const resourceURL = new URL( __object_isPrototypeOf(Request.prototype, resource) ? resource.url : pathToPosix(resource), typeof Object(globalThis.process).cwd === 'function' ? 'file:' + pathToPosix(process.cwd()) + '/' : 'file:' ) if (resourceURL.protocol.toLowerCase() === 'file:') { return import('node:fs').then((fs) => { try { const stats = fs.statSync(resourceURL) const body = fs.createReadStream(resourceURL) return new Response(body, { status: 200, statusText: '', headers: { 'content-length': String(stats.size), date: new Date().toUTCString(), 'last-modified': new Date(stats.mtimeMs).toUTCString(), }, }) } catch (error) { const body = new Stream.Readable() body._read = () => {} body.push(null) return new Response(body, { status: 404, statusText: '', headers: { date: new Date().toUTCString(), }, }) } }) } else { return fetch$1(resource, init) } }, }.fetch function u(u, D) { for (var t = 0; t < D.length; t++) { var F = D[t] ;(F.enumerable = F.enumerable || !1), (F.configurable = !0), 'value' in F && (F.writable = !0), Object.defineProperty(u, F.key, F) } } function D(D, t, F) { return t && u(D.prototype, t), F && u(D, F), D } function t(u, D) { ;(null == D || D > u.length) && (D = u.length) for (var t = 0, F = new Array(D); t < D; t++) F[t] = u[t] return F } function F$1(u, D) { var F = ('undefined' != typeof Symbol && u[Symbol.iterator]) || u['@@iterator'] if (F) return (F = F.call(u)).next.bind(F) if ( Array.isArray(u) || (F = (function (u, D) { if (u) { if ('string' == typeof u) return t(u, D) var F = Object.prototype.toString.call(u).slice(8, -1) return ( 'Object' === F && u.constructor && (F = u.constructor.name), 'Map' === F || 'Set' === F ? Array.from(u) : 'Arguments' === F || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(F) ? t(u, D) : void 0 ) } })(u)) || (D && u && 'number' == typeof u.length) ) { F && (u = F) var e = 0 return function () { return e >= u.length ? { done: !0 } : { done: !1, value: u[e++] } } } throw new TypeError( 'Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.' ) } var e = /(?:[\$A-Z_a-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08C7\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1878\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u31A0-\u31BF\u31F0-\u31FF\u3400-\u4DBF\u4E00-\u9FFC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7BF\uA7C2-\uA7CA\uA7F5-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDD00-\uDD23\uDE80-\uDEA9\uDEB0\uDEB1\uDF00-\uDF1C\uDF27\uDF30-\uDF45\uDFB0-\uDFC4\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD44\uDD47\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC5F-\uDC61\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDEB8\uDF00-\uDF1A]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCDF\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD2F\uDD3F\uDD41\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDEE0-\uDEF2\uDFB0]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD822\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879\uD880-\uD883][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE7F\uDF00-\uDF4A\uDF50\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3]|\uD821[\uDC00-\uDFF7]|\uD823[\uDC00-\uDCD5\uDD00-\uDD08]|\uD82C[\uDC00-\uDD1E\uDD50-\uDD52\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD838[\uDD00-\uDD2C\uDD37-\uDD3D\uDD4E\uDEC0-\uDEEB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43\uDD4B]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDEDD\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A])/, C = /(?:[\$0-9A-Z_a-z\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05EF-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u07FD\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08C7\u08D3-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u09FE\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B55-\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D81-\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1369-\u1371\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1878\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1ABF\u1AC0\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CD0-\u1CD2\u1CD4-\u1CFA\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u31A0-\u31BF\u31F0-\u31FF\u3400-\u4DBF\u4E00-\u9FFC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7BF\uA7C2-\uA7CA\uA7F5-\uA827\uA82C\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDD00-\uDD27\uDD30-\uDD39\uDE80-\uDEA9\uDEAB\uDEAC\uDEB0\uDEB1\uDF00-\uDF1C\uDF27\uDF30-\uDF50\uDFB0-\uDFC4\uDFE0-\uDFF6]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD44-\uDD47\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDC9-\uDDCC\uDDCE-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3B-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC5E-\uDC61\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB8\uDEC0-\uDEC9\uDF00-\uDF1A\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDC00-\uDC3A\uDCA0-\uDCE9\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD35\uDD37\uDD38\uDD3B-\uDD43\uDD50-\uDD59\uDDA0-\uDDA7\uDDAA-\uDDD7\uDDDA-\uDDE1\uDDE3\uDDE4\uDE00-\uDE3E\uDE47\uDE50-\uDE99\uDE9D\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD8E\uDD90\uDD91\uDD93-\uDD98\uDDA0-\uDDA9\uDEE0-\uDEF6\uDFB0]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD822\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879\uD880-\uD883][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE7F\uDF00-\uDF4A\uDF4F-\uDF87\uDF8F-\uDF9F\uDFE0\uDFE1\uDFE3\uDFE4\uDFF0\uDFF1]|\uD821[\uDC00-\uDFF7]|\uD823[\uDC00-\uDCD5\uDD00-\uDD08]|\uD82C[\uDC00-\uDD1E\uDD50-\uDD52\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A\uDD00-\uDD2C\uDD30-\uDD3D\uDD40-\uDD49\uDD4E\uDEC0-\uDEF9]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4B\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD83E[\uDFF0-\uDFF9]|\uD869[\uDC00-\uDEDD\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A]|\uDB40[\uDD00-\uDDEF])/ function A$1(u, D) { return (D ? /^[\x00-\xFF]*$/ : /^[\x00-\x7F]*$/).test(u) } function E(u, D) { void 0 === D && (D = !1) for (var t = [], F = 0; F < u.length; ) { var E = u[F], n = function (e) { if (!D) throw new TypeError(e) t.push({ type: 'INVALID_CHAR', index: F, value: u[F++] }) } if ('*' !== E) if ('+' !== E && '?' !== E) if ('\\' !== E) if ('{' !== E) if ('}' !== E) if (':' !== E) if ('(' !== E) t.push({ type: 'CHAR', index: F, value: u[F++] }) else { var r = 1, i = '', s = F + 1, a = !1 if ('?' === u[s]) { n('Pattern cannot start with "?" at ' + s) continue } for (; s < u.length; ) { if (!A$1(u[s], !1)) { n("Invalid character '" + u[s] + "' at " + s + '.'), (a = !0) break } if ('\\' !== u[s]) { if (')' === u[s]) { if (0 == --r) { s++ break } } else if ('(' === u[s] && (r++, '?' !== u[s + 1])) { n('Capturing groups are not allowed at ' + s), (a = !0) break } i += u[s++] } else i += u[s++] + u[s++] } if (a) continue if (r) { n('Unbalanced pattern at ' + F) continue } if (!i) { n('Missing pattern at ' + F) continue } t.push({ type: 'PATTERN', index: F, value: i }), (F = s) } else { for (var B = '', o = F + 1; o < u.length; ) { var h = u.substr(o, 1) if ( !((o === F + 1 && e.test(h)) || (o !== F + 1 && C.test(h))) ) break B += u[o++] } if (!B) { n('Missing parameter name at ' + F) continue } t.push({ type: 'NAME', index: F, value: B }), (F = o) } else t.push({ type: 'CLOSE', index: F, value: u[F++] }) else t.push({ type: 'OPEN', index: F, value: u[F++] }) else t.push({ type: 'ESCAPED_CHAR', index: F++, value: u[F++] }) else t.push({ type: 'MODIFIER', index: F, value: u[F++] }) else t.push({ type: 'ASTERISK', index: F, value: u[F++] }) } return t.push({ type: 'END', index: F, value: '' }), t } function n(u, D) { void 0 === D && (D = {}) for ( var t = E(u), F = D.prefixes, e = void 0 === F ? './' : F, C = '[^' + r(D.delimiter || '/#?') + ']+?', A = [], n = 0, i = 0, s = '', a = new Set(), B = function (u) { if (i < t.length && t[i].type === u) return t[i++].value }, o = function () { return B('MODIFIER') || B('ASTERISK') }, h = function (u) { var D = B(u) if (void 0 !== D) return D var F = t[i] throw new TypeError( 'Unexpected ' + F.type + ' at ' + F.index + ', expected ' + u ) }, p = function () { for (var u, D = ''; (u = B('CHAR') || B('ESCAPED_CHAR')); ) D += u return D }, c = D.encodePart || function (u) { return u }; i < t.length; ) { var f = B('CHAR'), l = B('NAME'), m = B('PATTERN') if ((l || m || !B('ASTERISK') || (m = '.*'), l || m)) { var d = f || '' ;-1 === e.indexOf(d) && ((s += d), (d = '')), s && (A.push(c(s)), (s = '')) var g = l || n++ if (a.has(g)) throw new TypeError("Duplicate name '" + g + "'.") a.add(g), A.push({ name: g, prefix: c(d), suffix: '', pattern: m || C, modifier: o() || '', }) } else { var x = f || B('ESCAPED_CHAR') if (x) s += x else if (B('OPEN')) { var S = p(), v = B('NAME') || '', y = B('PATTERN') || '' v || y || !B('ASTERISK') || (y = '.*') var R = p() h('CLOSE') var k = o() || '' if (!v && !y && !k) { s += S continue } if (!v && !y && !S) continue s && (A.push(c(s)), (s = '')), A.push({ name: v || (y ? n++ : ''), pattern: v && !y ? C : y, prefix: c(S), suffix: c(R), modifier: k, }) } else s && (A.push(c(s)), (s = '')), h('END') } } return A } function r(u) { return u.replace(/([.+*?^${}()[\]|/\\])/g, '\\$1') } function i(u) { return u && u.sensitive ? 'u' : 'ui' } function s$1(u, D, t) { void 0 === t && (t = {}) for ( var e, C = t.strict, A = void 0 !== C && C, E = t.start, n = void 0 === E || E, s = t.end, a = void 0 === s || s, B = t.encode, o = void 0 === B ? function (u) { return u } : B, h = '[' + r(t.endsWith || '') + ']|$', p = '[' + r(t.delimiter || '/#?') + ']', c = n ? '^' : '', f = F$1(u); !(e = f()).done; ) { var l = e.value if ('string' == typeof l) c += r(o(l)) else { var m = r(o(l.prefix)), d = r(o(l.suffix)) l.pattern ? (D && D.push(l), (c += m || d ? '+' === l.modifier || '*' === l.modifier ? '(?:' + m + '((?:' + l.pattern + ')(?:' + d + m + '(?:' + l.pattern + '))*)' + d + ')' + ('*' === l.modifier ? '?' : '') : '(?:' + m + '(' + l.pattern + ')' + d + ')' + l.modifier : '+' === l.modifier || '*' === l.modifier ? '((?:' + l.pattern + ')' + l.modifier + ')' : '(' + l.pattern + ')' + l.modifier)) : (c += '(?:' + m + d + ')' + l.modifier) } } if (a) A || (c += p + '?'), (c += t.endsWith ? '(?=' + h + ')' : '$') else { var g = u[u.length - 1], x = 'string' == typeof g ? p.indexOf(g[g.length - 1]) > -1 : void 0 === g A || (c += '(?:' + p + '(?=' + h + '))?'), x || (c += '(?=' + p + '|' + h + ')') } return new RegExp(c, i(t)) } function a(u, D, t) { return u instanceof RegExp ? (function (u, D) { if (!D) return u for ( var t = /\((?:\?<(.*?)>)?(?!\?)/g, F = 0, e = t.exec(u.source); e; ) D.push({ name: e[1] || F++, prefix: '', suffix: '', modifier: '', pattern: '', }), (e = t.exec(u.source)) return u })(u, D) : Array.isArray(u) ? (function (u, D, t) { var F = u.map(function (u) { return a(u, D, t).source }) return new RegExp('(?:' + F.join('|') + ')', i(t)) })(u, D, t) : (function (u, D, t) { return s$1(n(u, t), D, t) })(u, D, t) } var B = { delimiter: '', prefixes: '', sensitive: !0, strict: !0 }, o = { delimiter: '.', prefixes: '', sensitive: !0, strict: !0 }, h = { delimiter: '/', prefixes: '/', sensitive: !0, strict: !0 } function p(u, D) { return u.startsWith(D) ? u.substring(D.length, u.length) : u } function c(u) { return !( !u || u.length < 2 || ('[' !== u[0] && (('\\' !== u[0] && '{' !== u[0]) || '[' !== u[1])) ) } var f$1, l = ['ftp', 'file', 'http', 'https', 'ws', 'wss'] function m(u) { if (!u) return !0 for (var D, t = F$1(l); !(D = t()).done; ) if (u.test(D.value)) return !0 return !1 } function d(u) { switch (u) { case 'ws': case 'http': return '80' case 'wws': case 'https': return '443' case 'ftp': return '21' default: return '' } } function g(u) { if ('' === u) return u if (/^[-+.A-Za-z0-9]*$/.test(u)) return u.toLowerCase() throw new TypeError("Invalid protocol '" + u + "'.") } function x(u) { if ('' === u) return u var D = new URL('https://example.com') return (D.username = u), D.username } function S$1(u) { if ('' === u) return u var D = new URL('https://example.com') return (D.password = u), D.password } function v(u) { if ('' === u) return u if (/[\t\n\r #%/:<>?@[\]^\\|]/g.test(u)) throw new TypeError("Invalid hostname '" + u + "'") var D = new URL('https://example.com') return (D.hostname = u), D.hostname } function y(u) { if ('' === u) return u if (/[^0-9a-fA-F[\]:]/g.test(u)) throw new TypeError("Invalid IPv6 hostname '" + u + "'") return u.toLowerCase() } function R(u) { if ('' === u) return u if (/^[0-9]*$/.test(u) && parseInt(u) <= 65535) return u throw new TypeError("Invalid port '" + u + "'.") } function k(u) { if ('' === u) return u var D = new URL('https://example.com') return ( (D.pathname = '/' !== u[0] ? '/-' + u : u), '/' !== u[0] ? D.pathname.substring(2, D.pathname.length) : D.pathname ) } function w(u) { return '' === u ? u : new URL('data:' + u).pathname } function P(u) { if ('' === u) return u var D = new URL('https://example.com') return (D.search = u), D.search.substring(1, D.search.length) } function T(u) { if ('' === u) return u var D = new URL('https://example.com') return (D.hash = u), D.hash.substring(1, D.hash.length) } !(function (u) { ;(u[(u.INIT = 0)] = 'INIT'), (u[(u.PROTOCOL = 1)] = 'PROTOCOL'), (u[(u.AUTHORITY = 2)] = 'AUTHORITY'), (u[(u.USERNAME = 3)] = 'USERNAME'), (u[(u.PASSWORD = 4)] = 'PASSWORD'), (u[(u.HOSTNAME = 5)] = 'HOSTNAME'), (u[(u.PORT = 6)] = 'PORT'), (u[(u.PATHNAME = 7)] = 'PATHNAME'), (u[(u.SEARCH = 8)] = 'SEARCH'), (u[(u.HASH = 9)] = 'HASH'), (u[(u.DONE = 10)] = 'DONE') })(f$1 || (f$1 = {})) var b = (function () { function u(u) { ;(this.input = void 0), (this.tokenList = []), (this.internalResult = {}), (this.tokenIndex = 0), (this.tokenIncrement = 1), (this.componentStart = 0), (this.state = f$1.INIT), (this.groupDepth = 0), (this.hostnameIPv6BracketDepth = 0), (this.shouldTreatAsStandardURL = !1), (this.input = u) } var t = u.prototype return ( (t.parse = function () { for ( this.tokenList = E(this.input, !0); this.tokenIndex < this.tokenList.length; this.tokenIndex += this.tokenIncrement ) { if ( ((this.tokenIncrement = 1), 'END' === this.tokenList[this.tokenIndex].type) ) { if (this.state === f$1.INIT) { this.rewind(), this.isHashPrefix() ? this.changeState(f$1.HASH, 1) : this.isSearchPrefix() ? (this.changeState(f$1.SEARCH, 1), (this.internalResult.hash = '')) : (this.changeState(f$1.PATHNAME, 0), (this.internalResult.search = ''), (this.internalResult.hash = '')) continue } if (this.state === f$1.AUTHORITY) { this.rewindAndSetState(f$1.HOSTNAME) continue } this.changeState(f$1.DONE, 0) break } if (this.groupDepth > 0) { if (!this.isGroupClose()) continue this.groupDepth -= 1 } if (this.isGroupOpen()) this.groupDepth += 1 else switch (this.state) { case f$1.INIT: this.isProtocolSuffix() && ((this.internalResult.username = ''), (this.internalResult.password = ''), (this.internalResult.hostname = ''), (this.internalResult.port = ''), (this.internalResult.pathname = ''), (this.internalResult.search = ''), (this.internalResult.hash = ''), this.rewindAndSetState(f$1.PROTOCOL)) break case f$1.PROTOCOL: if (this.isProtocolSuffix()) { this.computeShouldTreatAsStandardURL() var u = f$1.PATHNAME, D = 1 this.shouldTreatAsStandardURL && (this.internalResult.pathname = '/'), this.nextIsAuthoritySlashes() ? ((u = f$1.AUTHORITY), (D = 3)) : this.shouldTreatAsStandardURL && (u = f$1.AUTHORITY), this.changeState(u, D) } break case f$1.AUTHORITY: this.isIdentityTerminator() ? this.rewindAndSetState(f$1.USERNAME) : (this.isPathnameStart() || this.isSearchPrefix() || this.isHashPrefix()) && this.rewindAndSetState(f$1.HOSTNAME) break case f$1.USERNAME: this.isPasswordPrefix() ? this.changeState(f$1.PASSWORD, 1) : this.isIdentityTerminator() && this.changeState(f$1.HOSTNAME, 1) break case f$1.PASSWORD: this.isIdentityTerminator() && this.changeState(f$1.HOSTNAME, 1) break case f$1.HOSTNAME: this.isIPv6Open() ? (this.hostnameIPv6BracketDepth += 1) : this.isIPv6Close() && (this.hostnameIPv6BracketDepth -= 1), this.isPortPrefix() && !this.hostnameIPv6BracketDepth ? this.changeState(f$1.PORT, 1) : this.isPathnameStart() ? this.changeState(f$1.PATHNAME, 0) : this.isSearchPrefix() ? this.changeState(f$1.SEARCH, 1) : this.isHashPrefix() && this.changeState(f$1.HASH, 1) break case f$1.PORT: this.isPathnameStart() ? this.changeState(f$1.PATHNAME, 0) : this.isSearchPrefix() ? this.changeState(f$1.SEARCH, 1) : this.isHashPrefix() && this.changeState(f$1.HASH, 1) break case f$1.PATHNAME: this.isSearchPrefix() ? this.changeState(f$1.SEARCH, 1) : this.isHashPrefix() && this.changeState(f$1.HASH, 1) break case f$1.SEARCH: this.isHashPrefix() && this.changeState(f$1.HASH, 1) } } }), (t.changeState = function (u, D) { switch (this.state) { case f$1.INIT: break case f$1.PROTOCOL: this.internalResult.protocol = this.makeComponentString() break case f$1.AUTHORITY: break case f$1.USERNAME: this.internalResult.username = this.makeComponentString() break case f$1.PASSWORD: this.internalResult.password = this.makeComponentString() break case f$1.HOSTNAME: this.internalResult.hostname = this.makeComponentString() break case f$1.PORT: this.internalResult.port = this.makeComponentString() break case f$1.PATHNAME: this.internalResult.pathname = this.makeComponentString() break case f$1.SEARCH: this.internalResult.search = this.makeComponentString() break case f$1.HASH: this.internalResult.hash = this.makeComponentString() } this.changeStateWithoutSettingComponent(u, D) }), (t.changeStateWithoutSettingComponent = function (u, D) { ;(this.state = u), (this.componentStart = this.tokenIndex + D), (this.tokenIndex += D), (this.tokenIncrement = 0) }), (t.rewind = function () { ;(this.tokenIndex = this.componentStart), (this.tokenIncrement = 0) }), (t.rewindAndSetState = function (u) { this.rewind(), (this.state = u) }), (t.safeToken = function (u) { return ( u < 0 && (u = this.tokenList.length - u), u < this.tokenList.length ? this.tokenList[u] : this.tokenList[this.tokenList.length - 1] ) }), (t.isNonSpecialPatternChar = function (u, D) { var t = this.safeToken(u) return ( t.value === D && ('CHAR' === t.type || 'ESCAPED_CHAR' === t.type || 'INVALID_CHAR' === t.type) ) }), (t.isProtocolSuffix = function () { return this.isNonSpecialPatternChar(this.tokenIndex, ':') }), (t.nextIsAuthoritySlashes = function () { return ( this.isNonSpecialPatternChar(this.tokenIndex + 1, '/') && this.isNonSpecialPatternChar(this.tokenIndex + 2, '/') ) }), (t.isIdentityTerminator = function () { return this.isNonSpecialPatternChar(this.tokenIndex, '@') }), (t.isPasswordPrefix = function () { return this.isNonSpecialPatternChar(this.tokenIndex, ':') }), (t.isPortPrefix = function () { return this.isNonSpecialPatternChar(this.tokenIndex, ':') }), (t.isPathnameStart = function () { return this.isNonSpecialPatternChar(this.tokenIndex, '/') }), (t.isSearchPrefix = function () { if (this.isNonSpecialPatternChar(this.tokenIndex, '?')) return !0 if ('?' !== this.tokenList[this.tokenIndex].value) return !1 var u = this.safeToken(this.tokenIndex - 1) return ( 'NAME' !== u.type && 'PATTERN' !== u.type && 'CLOSE' !== u.type && 'ASTERISK' !== u.type ) }), (t.isHashPrefix = function () { return this.isNonSpecialPatternChar(this.tokenIndex, '#') }), (t.isGroupOpen = function () { return 'OPEN' == this.tokenList[this.tokenIndex].type }), (t.isGroupClose = function () { return 'CLOSE' == this.tokenList[this.tokenIndex].type }), (t.isIPv6Open = function () { return this.isNonSpecialPatternChar(this.tokenIndex, '[') }), (t.isIPv6Close = function () { return this.isNonSpecialPatternChar(this.tokenIndex, ']') }), (t.makeComponentString = function () { var u = this.tokenList[this.tokenIndex], D = this.safeToken(this.componentStart).index return this.input.substring(D, u.index) }), (t.computeShouldTreatAsStandardURL = function () { var u = {} Object.assign(u, B), (u.encodePart = g) var D = a(this.makeComponentString(), void 0, u) this.shouldTreatAsStandardURL = m(D) }), D(u, [ { key: 'result', get: function () { return this.internalResult }, }, ]), u ) })(), I = [ 'protocol', 'username', 'password', 'hostname', 'port', 'pathname', 'search', 'hash', ] function O(u, D) { if ('string' != typeof u) throw new TypeError("parameter 1 is not of type 'string'.") var t = new URL(u, D) return { protocol: t.protocol.substring(0, t.protocol.length - 1), username: t.username, password: t.password, hostname: t.hostname, port: t.port, pathname: t.pathname, search: '' != t.search ? t.search.substring(1, t.search.length) : void 0, hash: '' != t.hash ? t.hash.substring(1, t.hash.length) : void 0, } } function H(u, D, t) { var F if ('string' == typeof D.baseURL) try { ;(F = new URL(D.baseURL)), (u.protocol = F.protocol ? F.protocol.substring(0, F.protocol.length - 1) : ''), (u.username = F.username), (u.password = F.password), (u.hostname = F.hostname), (u.port = F.port), (u.pathname = F.pathname), (u.search = F.search ? F.search.substring(1, F.search.length) : ''), (u.hash = F.hash ? F.hash.substring(1, F.hash.length) : '') } catch (u) { throw new TypeError("invalid baseURL '" + D.baseURL + "'.") } if ( ('string' == typeof D.protocol && (u.protocol = (function (u, D) { var t return ( (u = (t = u).endsWith(':') ? t.substr(0, t.length - ':'.length) : t), D || '' === u ? u : g(u) ) })(D.protocol, t)), 'string' == typeof D.username && (u.username = (function (u, D) { if (D || '' === u) return u var t = new URL('https://example.com') return (t.username = u), t.username })(D.username, t)), 'string' == typeof D.password && (u.password = (function (u, D) { if (D || '' === u) return u var t = new URL('https://example.com') return (t.password = u), t.password })(D.password, t)), 'string' == typeof D.hostname && (u.hostname = (function (u, D) { return D || '' === u ? u : c(u) ? y(u) : v(u) })(D.hostname, t)), 'string' == typeof D.port && (u.port = (function (u, D, t) { return d(D) === u && (u = ''), t || '' === u ? u : R(u) })(D.port, u.protocol, t)), 'string' == typeof D.pathname) ) { if ( ((u.pathname = D.pathname), F && !(function (u, D) { return !( !u.length || ('/' !== u[0] && (!D || u.length < 2 || ('\\' != u[0] && '{' != u[0]) || '/' != u[1])) ) })(u.pathname, t)) ) { var e = F.pathname.lastIndexOf('/') e >= 0 && (u.pathname = F.pathname.substring(0, e + 1) + u.pathname) } u.pathname = (function (u, D, t) { if (t || '' === u) return u if (D && !l.includes(D)) return new URL(D + ':' + u).pathname var F = '/' == u[0] return ( (u = new URL(F ? u : '/-' + u, 'https://example.com').pathname), F || (u = u.substring(2, u.length)), u ) })(u.pathname, u.protocol, t) } return ( 'string' == typeof D.search && (u.search = (function (u, D) { if (((u = p(u, '?')), D || '' === u)) return u var t = new URL('https://example.com') return ( (t.search = u), t.search ? t.search.substring(1, t.search.length) : '' ) })(D.search, t)), 'string' == typeof D.hash && (u.hash = (function (u, D) { if (((u = p(u, '#')), D || '' === u)) return u var t = new URL('https://example.com') return (t.hash = u), t.hash ? t.hash.substring(1, t.hash.length) : '' })(D.hash, t)), u ) } function N(u) { return u.replace(/([+*?:{}()\\])/g, '\\$1') } function L(u, D) { for ( var t = '[^' + (D.delimiter || '/#?').replace(/([.+*?^${}()[\]|/\\])/g, '\\$1') + ']+?', F = /(?:[\$0-9A-Z_a-z\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05EF-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u07FD\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08C7\u08D3-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u09FE\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B55-\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D81-\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1369-\u1371\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1878\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1ABF\u1AC0\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CD0-\u1CD2\u1CD4-\u1CFA\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u31A0-\u31BF\u31F0-\u31FF\u3400-\u4DBF\u4E00-\u9FFC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7BF\uA7C2-\uA7CA\uA7F5-\uA827\uA82C\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDD00-\uDD27\uDD30-\uDD39\uDE80-\uDEA9\uDEAB\uDEAC\uDEB0\uDEB1\uDF00-\uDF1C\uDF27\uDF30-\uDF50\uDFB0-\uDFC4\uDFE0-\uDFF6]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD44-\uDD47\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDC9-\uDDCC\uDDCE-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3B-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC5E-\uDC61\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB8\uDEC0-\uDEC9\uDF00-\uDF1A\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDC00-\uDC3A\uDCA0-\uDCE9\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD35\uDD37\uDD38\uDD3B-\uDD43\uDD50-\uDD59\uDDA0-\uDDA7\uDDAA-\uDDD7\uDDDA-\uDDE1\uDDE3\uDDE4\uDE00-\uDE3E\uDE47\uDE50-\uDE99\uDE9D\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD8E\uDD90\uDD91\uDD93-\uDD98\uDDA0-\uDDA9\uDEE0-\uDEF6\uDFB0]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD822\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879\uD880-\uD883][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE7F\uDF00-\uDF4A\uDF4F-\uDF87\uDF8F-\uDF9F\uDFE0\uDFE1\uDFE3\uDFE4\uDFF0\uDFF1]|\uD821[\uDC00-\uDFF7]|\uD823[\uDC00-\uDCD5\uDD00-\uDD08]|\uD82C[\uDC00-\uDD1E\uDD50-\uDD52\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A\uDD00-\uDD2C\uDD30-\uDD3D\uDD40-\uDD49\uDD4E\uDEC0-\uDEF9]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4B\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD83E[\uDFF0-\uDFF9]|\uD869[\uDC00-\uDEDD\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A]|\uDB40[\uDD00-\uDDEF])/, e = '', C = 0; C < u.length; ++C ) { var A = u[C], E = C > 0 ? u[C - 1] : null, n = C < u.length - 1 ? u[C + 1] : null if ('string' != typeof A) if ('' !== A.pattern) { var r = 'number' != typeof A.name, i = void 0 !== D.prefixes ? D.prefixes : './', s = '' !== A.suffix || ('' !== A.prefix && (1 !== A.prefix.length || !i.includes(A.prefix))) s || !r || A.pattern !== t || '' !== A.modifier || !n || n.prefix || n.suffix || (s = 'string' == typeof n ? F.test(n.length > 0 ? n[0] : '') : 'number' == typeof n.name), !s && '' === A.prefix && E && 'string' == typeof E && E.length > 0 && (s = i.includes(E[E.length - 1])), s && (e += '{'), (e += N(A.prefix)), r && (e += ':' + A.name), '.*' === A.pattern ? (e += r || (E && 'string' != typeof E && !E.modifier && !s && '' === A.prefix) ? '(.*)' : '*') : A.pattern === t ? r || (e += '(' + t + ')') : (e += '(' + A.pattern + ')'), A.pattern === t && r && '' !== A.suffix && F.test(A.suffix[0]) && (e += '\\'), (e += N(A.suffix)), s && (e += '}'), (e += A.modifier) } else { if ('' === A.modifier) { e += N(A.prefix) continue } e += '{' + N(A.prefix) + '}' + A.modifier } else e += N(A) } return e } var U = (function () { function u(u, D) { void 0 === u && (u = {}), (this.pattern = void 0), (this.regexp = {}), (this.keys = {}), (this.component_pattern = {}) try { if ('string' == typeof u) { var t = new b(u) if ((t.parse(), (u = t.result), D)) { if ('string' != typeof D) throw new TypeError("'baseURL' parameter is not of type 'string'.") u.baseURL = D } else if ('string' != typeof u.protocol) throw new TypeError( 'A base URL must be provided for a relative constructor string.' ) } else if (D) throw new TypeError("parameter 1 is not of type 'string'.") if (!u || 'object' != typeof u) throw new TypeError( "parameter 1 is not of type 'string' and cannot convert to dictionary." ) var e ;(this.pattern = H( { pathname: '*', protocol: '*', username: '*', password: '*', hostname: '*', port: '*', search: '*', hash: '*', }, u, !0 )), d(this.pattern.protocol) === this.pattern.port && (this.pattern.port = '') for (var C, A = F$1(I); !(C = A()).done; ) if ((e = C.value) in this.pattern) { var E = {}, r = this.pattern[e] switch (((this.keys[e] = []), e)) { case 'protocol': Object.assign(E, B), (E.encodePart = g) break case 'username': Object.assign(E, B), (E.encodePart = x) break case 'password': Object.assign(E, B), (E.encodePart = S$1) break case 'hostname': Object.assign(E, o), (E.encodePart = c(r) ? y : v) break case 'port': Object.assign(E, B), (E.encodePart = R) break case 'pathname': m(this.regexp.protocol) ? (Object.assign(E, h), (E.encodePart = k)) : (Object.assign(E, B), (E.encodePart = w)) break case 'search': Object.assign(E, B), (E.encodePart = P) break case 'hash': Object.assign(E, B), (E.encodePart = T) } try { var i = n(r, E) ;(this.regexp[e] = s$1(i, this.keys[e], E)), (this.component_pattern[e] = L(i, E)) } catch (u) { throw new TypeError( 'invalid ' + e + " pattern '" + this.pattern[e] + "'." ) } } } catch (u) { throw new TypeError("Failed to construct 'URLPattern': " + u.message) } } var t = u.prototype return ( (t.test = function (u, D) { void 0 === u && (u = {}) var t, F = { pathname: '', protocol: '', username: '', password: '', hostname: '', port: '', search: '', hash: '', } if ('string' != typeof u && D) throw new TypeError("parameter 1 is not of type 'string'.") if (void 0 === u) return !1 try { F = H(F, 'object' == typeof u ? u : O(u, D), !1) } catch (u) { return !1 } for (t in this.pattern) if (!this.regexp[t].exec(F[t])) return !1 return !0 }), (t.exec = function (u, D) { void 0 === u && (u = {}) var t = { pathname: '', protocol: '', username: '', password: '', hostname: '', port: '', search: '', hash: '', } if ('string' != typeof u && D) throw new TypeError("parameter 1 is not of type 'string'.") if (void 0 !== u) { try { t = H(t, 'object' == typeof u ? u : O(u, D), !1) } catch (u) { return null } var e, C = {} for (e in ((C.inputs = D ? [u, D] : [u]), this.pattern)) { var A = this.regexp[e].exec(t[e]) if (!A) return null for ( var E, n = {}, r = F$1(this.keys[e].entries()); !(E = r()).done; ) { var i = E.value, s = i[1] ;('string' != typeof s.name && 'number' != typeof s.name) || (n[s.name] = A[i[0] + 1] || '') } C[e] = { input: t[e] || '', groups: n } } return C } }), D(u, [ { key: 'protocol', get: function () { return this.component_pattern.protocol }, }, { key: 'username', get: function () { return this.component_pattern.username }, }, { key: 'password', get: function () { return this.component_pattern.password }, }, { key: 'hostname', get: function () { return this.component_pattern.hostname }, }, { key: 'port', get: function () { return this.component_pattern.port }, }, { key: 'pathname', get: function () { return this.component_pattern.pathname }, }, { key: 'search', get: function () { return this.component_pattern.search }, }, { key: 'hash', get: function () { return this.component_pattern.hash }, }, ]), u ) })() const INTERNAL = { tick: 0, pool: new Map() } function setTimeout(callback, delay = 0, ...args) { const func = __function_bind(callback, globalThis) const tick = ++INTERNAL.tick const timeout = setTimeout$1(func, delay, ...args) INTERNAL.pool.set(tick, timeout) return tick } function clearTimeout(timeoutId) { const timeout = INTERNAL.pool.get(timeoutId) if (timeout) { clearTimeout$1(timeout) INTERNAL.pool.delete(timeoutId) } } const PRIMITIVE = 0 const ARRAY = 1 const OBJECT = 2 const DATE = 3 const REGEXP = 4 const MAP = 5 const SET = 6 const ERROR = 7 const BIGINT = 8 // export const SYMBOL = 9; const env = typeof self === 'object' ? self : globalThis const deserializer = ($, _) => { const as = (out, index) => { $.set(index, out) return out } const unpair = (index) => { if ($.has(index)) return $.get(index) const [type, value] = _[index] switch (type) { case PRIMITIVE: return as(value, index) case ARRAY: { const arr = as([], index) for (const index of value) arr.push(unpair(index)) return arr } case OBJECT: { const object = as({}, index) for (const [key, index] of value) object[unpair(key)] = unpair(index) return object } case DATE: return as(new Date(value), index) case REGEXP: { const { source, flags } = value return as(new RegExp(source, flags), index) } case MAP: { const map = as(new Map(), index) for (const [key, index] of value) map.set(unpair(key), unpair(index)) return map } case SET: { const set = as(new Set(), index) for (const index of value) set.add(unpair(index)) return set } case ERROR: { const { name, message } = value return as(new env[name](message), index) } case BIGINT: return as(BigInt(value), index) case 'BigInt': return as(Object(BigInt(value)), index) } return as(new env[type](value), index) } return unpair } /** * @typedef {Array} Record a type representation */ /** * Returns a deserialized value from a serialized array of Records. * @param {Record[]} serialized a previously serialized value. * @returns {any} */ const deserialize = (serialized) => deserializer(new Map(), serialized)(0) const EMPTY = '' const { toString } = {} const { keys } = Object const typeOf = (value) => { const type = typeof value if (type !== 'object' || !value) return [PRIMITIVE, type] const asString = toString.call(value).slice(8, -1) switch (asString) { case 'Array': return [ARRAY, EMPTY] case 'Object': return [OBJECT, EMPTY] case 'Date': return [DATE, EMPTY] case 'RegExp': return [REGEXP, EMPTY] case 'Map': return [MAP, EMPTY] case 'Set': return [SET, EMPTY] } if (asString.includes('Array')) return [ARRAY, asString] if (asString.includes('Error')) return [ERROR, asString] return [OBJECT, asString] } const shouldSkip = ([TYPE, type]) => TYPE === PRIMITIVE && (type === 'function' || type === 'symbol') const serializer = (strict, json, $, _) => { const as = (out, value) => { const index = _.push(out) - 1 $.set(value, index) return index } const pair = (value) => { if ($.has(value)) return $.get(value) let [TYPE, type] = typeOf(value) switch (TYPE) { case PRIMITIVE: { let entry = value switch (type) { case 'bigint': TYPE = BIGINT entry = value.toString() break case 'function': case 'symbol': if (strict) throw new TypeError('unable to serialize ' + type) entry = null break } return as([TYPE, entry], value) } case ARRAY: { if (type) return as([type, [...value]], value) const arr = [] const index = as([TYPE, arr], value) for (const entry of value) arr.push(pair(entry)) return index } case OBJECT: { if (type) { switch (type) { case 'BigInt': return as([type, value.toString()], value) case 'Boolean': case 'Number': case 'String': return as([type, value.valueOf()], value) } } if (json && 'toJSON' in value) return pair(value.toJSON()) const entries = [] const index = as([TYPE, entries], value) for (const key of keys(value)) { if (strict || !shouldSkip(typeOf(value[key]))) entries.push([pair(key), pair(value[key])]) } return index } case DATE: return as([TYPE, value.toISOString()], value) case REGEXP: { const { source, flags } = value return as([TYPE, { source, flags }], value) } case MAP: { const entries = [] const index = as([TYPE, entries], value) for (const [key, entry] of value) { if (strict || !(shouldSkip(typeOf(key)) || shouldSkip(typeOf(entry)))) entries.push([pair(key), pair(entry)]) } return index } case SET: { const entries = [] const index = as([TYPE, entries], value) for (const entry of value) { if (strict || !shouldSkip(typeOf(entry))) entries.push(pair(entry)) } return index } } const { message } = value return as([TYPE, { name: type, message }], value) } return pair } /** * @typedef {Array} Record a type representation */ /** * Returns an array of serialized Records. * @param {any} value a serializable value. * @param {{lossy?: boolean}?} options an object with a `lossy` property that, * if `true`, will not throw errors on incompatible types, and behave more * like JSON stringify would behave. Symbol and Function will be discarded. * @returns {Record[]} */ const serialize = (value, { json, lossy } = {}) => { const _ = [] return serializer(!(json || lossy), !!json, new Map(), _)(value), _ } var structuredClone = (any, options) => deserialize(serialize(any, options)) class ImageData { constructor(arg0, arg1, ...args) { if (arguments.length < 2) throw new TypeError( `Failed to construct 'ImageData': 2 arguments required.` ) /** Whether Uint8ClampedArray data is provided. */ const hasData = __object_isPrototypeOf(Uint8ClampedArray.prototype, arg0) /** Image data, either provided or calculated. */ const d = hasData ? arg0 : new Uint8ClampedArray( asNumber(arg0, 'width') * asNumber(arg1, 'height') * 4 ) /** Image width. */ const w = asNumber(hasData ? arg1 : arg0, 'width') /** Image height. */ const h = d.length / w / 4 /** Image color space. */ const c = String(Object(hasData ? args[1] : args[0]).colorSpace || 'srgb') // throw if a provided height does not match the calculated height if (args.length && asNumber(args[0], 'height') !== h) throw new DOMException( 'height is not equal to (4 * width * height)', 'IndexSizeError' ) // throw if a provided colorspace does not match a known colorspace if (c !== 'srgb' && c !== 'rec2020' && c !== 'display-p3') throw new TypeError('colorSpace is not known value') Object.defineProperty(this, 'data', { configurable: true, enumerable: true, value: d, }) INTERNALS$3.set(this, { width: w, height: h, colorSpace: c }) } get data() { internalsOf(this, 'ImageData', 'data') return Object.getOwnPropertyDescriptor(this, 'data').value } get width() { return internalsOf(this, 'ImageData', 'width').width } get height() { return internalsOf(this, 'ImageData', 'height').height } } allowStringTag(ImageData) /** Returns a coerced number, optionally throwing if the number is zero-ish. */ const asNumber = (value, axis) => { value = Number(value) || 0 if (value === 0) throw new TypeError(`The source ${axis} is zero or not a number.`) return value } class CanvasRenderingContext2D { get canvas() { return internalsOf(this, 'CanvasRenderingContext2D', 'canvas').canvas } get direction() { return internalsOf(this, 'CanvasRenderingContext2D', 'direction').direction } get fillStyle() { return internalsOf(this, 'CanvasRenderingContext2D', 'fillStyle').fillStyle } get filter() { return internalsOf(this, 'CanvasRenderingContext2D', 'filter').filter } get globalAlpha() { return internalsOf(this, 'CanvasRenderingContext2D', 'globalAlpha') .globalAlpha } get globalCompositeOperation() { return internalsOf( this, 'CanvasRenderingContext2D', 'globalCompositeOperation' ).globalCompositeOperation } get font() { return internalsOf(this, 'CanvasRenderingContext2D', 'font').font } get imageSmoothingEnabled() { return internalsOf( this, 'CanvasRenderingContext2D', 'imageSmoothingEnabled' ).imageSmoothingEnabled } get imageSmoothingQuality() { return internalsOf( this, 'CanvasRenderingContext2D', 'imageSmoothingQuality' ).imageSmoothingQuality } get lineCap() { return internalsOf(this, 'CanvasRenderingContext2D', 'lineCap').lineCap } get lineDashOffset() { return internalsOf(this, 'CanvasRenderingContext2D', 'lineDashOffset') .lineDashOffset } get lineJoin() { return internalsOf(this, 'CanvasRenderingContext2D', 'lineJoin').lineJoin } get lineWidth() { return internalsOf(this, 'CanvasRenderingContext2D', 'lineWidth').lineWidth } get miterLimit() { return internalsOf(this, 'CanvasRenderingContext2D', 'miterLimit') .miterLimit } get strokeStyle() { return internalsOf(this, 'CanvasRenderingContext2D', 'strokeStyle') .strokeStyle } get shadowOffsetX() { return internalsOf(this, 'CanvasRenderingContext2D', 'shadowOffsetX') .shadowOffsetX } get shadowOffsetY() { return internalsOf(this, 'CanvasRenderingContext2D', 'shadowOffsetY') .shadowOffsetY } get shadowBlur() { return internalsOf(this, 'CanvasRenderingContext2D', 'shadowBlur') .shadowBlur } get shadowColor() { return internalsOf(this, 'CanvasRenderingContext2D', 'shadowColor') .shadowColor } get textAlign() { return internalsOf(this, 'CanvasRenderingContext2D', 'textAlign').textAlign } get textBaseline() { return internalsOf(this, 'CanvasRenderingContext2D', 'textBaseline') .textBaseline } arc() {} arcTo() {} beginPath() {} bezierCurveTo() {} clearRect() {} clip() {} closePath() {} createImageData(arg0, arg1) { /** Whether ImageData is provided. */ const hasData = __object_isPrototypeOf(ImageData.prototype, arg0) const w = hasData ? arg0.width : arg0 const h = hasData ? arg0.height : arg1 const d = hasData ? arg0.data : new Uint8ClampedArray(w * h * 4) return new ImageData(d, w, h) } createLinearGradient() {} createPattern() {} createRadialGradient() {} drawFocusIfNeeded() {} drawImage() {} ellipse() {} fill() {} fillRect() {} fillText() {} getContextAttributes() {} getImageData() {} getLineDash() {} getTransform() {} isPointInPath() {} isPointInStroke() {} lineTo() {} measureText() {} moveTo() {} putImageData() {} quadraticCurveTo() {} rect() {} resetTransform() {} restore() {} rotate() {} save() {} scale() {} setLineDash() {} setTransform() {} stroke() {} strokeRect() {} strokeText() {} transform() {} translate() {} } allowStringTag(CanvasRenderingContext2D) const __createCanvasRenderingContext2D = (canvas) => { const renderingContext2D = Object.create(CanvasRenderingContext2D.prototype) INTERNALS$3.set(renderingContext2D, { canvas, direction: 'inherit', fillStyle: '#000', filter: 'none', font: '10px sans-serif', globalAlpha: 0, globalCompositeOperation: 'source-over', imageSmoothingEnabled: false, imageSmoothingQuality: 'high', lineCap: 'butt', lineDashOffset: 0.0, lineJoin: 'miter', lineWidth: 1.0, miterLimit: 10.0, shadowBlur: 0, shadowColor: '#000', shadowOffsetX: 0, shadowOffsetY: 0, strokeStyle: '#000', textAlign: 'start', textBaseline: 'alphabetic', }) return renderingContext2D } class StyleSheet {} class CSSStyleSheet extends StyleSheet { async replace(text) { return new CSSStyleSheet() } replaceSync(text) { return new CSSStyleSheet() } get cssRules() { return [] } } allowStringTag(StyleSheet) allowStringTag(CSSStyleSheet) class CustomElementRegistry { /** Defines a new custom element using the given tag name and HTMLElement constructor. */ define(name, constructor, options) { const internals = internalsOf(this, 'CustomElementRegistry', 'define') name = String(name) if (/[A-Z]/.test(name)) throw new SyntaxError( 'Custom element name cannot contain an uppercase ASCII letter' ) if (!/^[a-z]/.test(name)) throw new SyntaxError( 'Custom element name must have a lowercase ASCII letter as its first character' ) if (!/-/.test(name)) throw new SyntaxError('Custom element name must contain a hyphen') internals.constructorByName.set(name, constructor) internals.nameByConstructor.set(constructor, name) } /** Returns the constructor associated with the given tag name. */ get(name) { const internals = internalsOf(this, 'CustomElementRegistry', 'get') name = String(name).toLowerCase() return internals.constructorByName.get(name) } getName(constructor) { const internals = internalsOf(this, 'CustomElementRegistry', 'getName') return internals.nameByConstructor.get(constructor) } } allowStringTag(CustomElementRegistry) const initCustomElementRegistry = (target, exclude) => { if (exclude.has('customElements')) return const CustomElementRegistry = target.CustomElementRegistry || globalThis.CustomElementRegistry const customElements = (target.customElements = Object.create( CustomElementRegistry.prototype )) INTERNALS$3.set(customElements, { constructorByName: new Map(), nameByConstructor: new Map(), }) } class Element extends Node { hasAttribute(name) { return false } getAttribute(name) { return null } setAttribute(name, value) {} removeAttribute(name) {} attachShadow(init) { if (arguments.length < 1) throw new TypeError( `Failed to execute 'attachShadow' on 'Element': 1 argument required, but only 0 present.` ) if (init !== Object(init)) throw new TypeError( `Failed to execute 'attachShadow' on 'Element': The provided value is not of type 'ShadowRootInit'.` ) if (init.mode !== 'open' && init.mode !== 'closed') throw new TypeError( `Failed to execute 'attachShadow' on 'Element': Failed to read the 'mode' property from 'ShadowRootInit': The provided value '${init.mode}' is not a valid enum value of type ShadowRootMode.` ) const internals = internalsOf(this, 'Element', 'attachShadow') if (internals.shadowRoot) throw new Error('The operation is not supported.') internals.shadowInit = internals.shadowInit || { mode: init.mode, delegatesFocus: Boolean(init.delegatesFocus), } internals.shadowRoot = internals.shadowRoot || (/^open$/.test(internals.shadowInit.mode) ? Object.setPrototypeOf(new EventTarget(), ShadowRoot.prototype) : null) return internals.shadowRoot } get assignedSlot() { return null } get innerHTML() { internalsOf(this, 'Element', 'innerHTML') return '' } set innerHTML(value) { internalsOf(this, 'Element', 'innerHTML') } get shadowRoot() { const internals = internalsOf(this, 'Element', 'shadowRoot') return Object(internals.shadowInit).mode === 'open' ? internals.shadowRoot : null } get localName() { return internalsOf(this, 'Element', 'localName').localName } get nodeName() { return internalsOf(this, 'Element', 'nodeName').localName.toUpperCase() } get tagName() { return internalsOf(this, 'Element', 'tagName').localName.toUpperCase() } } class HTMLElement extends Element {} class HTMLBodyElement extends HTMLElement {} class HTMLDivElement extends HTMLElement {} class HTMLHeadElement extends HTMLElement {} class HTMLHtmlElement extends HTMLElement {} class HTMLSpanElement extends HTMLElement {} class HTMLStyleElement extends HTMLElement {} class HTMLTemplateElement extends HTMLElement {} class HTMLUnknownElement extends HTMLElement {} allowStringTag(Element) allowStringTag(HTMLElement) allowStringTag(HTMLBodyElement) allowStringTag(HTMLDivElement) allowStringTag(HTMLHeadElement) allowStringTag(HTMLHtmlElement) allowStringTag(HTMLSpanElement) allowStringTag(HTMLStyleElement) allowStringTag(HTMLTemplateElement) allowStringTag(HTMLUnknownElement) class Document extends Node { createElement(name) { const internals = internalsOf(this, 'Document', 'createElement') const customElementInternals = INTERNALS$3.get( internals.target.customElements ) name = String(name).toLowerCase() const TypeOfHTMLElement = internals.constructorByName.get(name) || (customElementInternals && customElementInternals.constructorByName.get(name)) || HTMLUnknownElement const element = Object.setPrototypeOf( new EventTarget(), TypeOfHTMLElement.prototype ) INTERNALS$3.set(element, { attributes: {}, localName: name, ownerDocument: this, shadowInit: null, shadowRoot: null, }) return element } createNodeIterator(root, whatToShow = NodeFilter.SHOW_ALL, filter) { const target = Object.create(NodeIterator.prototype) INTERNALS$3.set(target, { filter, pointerBeforeReferenceNode: false, referenceNode: root, root, whatToShow, }) return target } createTextNode(data) { return new Text(data) } createTreeWalker( root, whatToShow = NodeFilter.SHOW_ALL, filter, expandEntityReferences ) { const target = Object.create(TreeWalker.prototype) INTERNALS$3.set(target, { filter, currentNode: root, root, whatToShow }) return target } get adoptedStyleSheets() { return [] } get styleSheets() { return [] } } class HTMLDocument extends Document {} allowStringTag(Document) allowStringTag(HTMLDocument) const initDocument = (target, exclude) => { if (exclude.has('document')) return const EventTarget = target.EventTarget || globalThis.EventTarget const HTMLDocument = target.HTMLDocument || globalThis.HTMLDocument const document = (target.document = Object.setPrototypeOf( new EventTarget(), HTMLDocument.prototype )) INTERNALS$3.set(document, { target, constructorByName: new Map([ ['body', target.HTMLBodyElement], ['canvas', target.HTMLCanvasElement], ['div', target.HTMLDivElement], ['head', target.HTMLHeadElement], ['html', target.HTMLHtmlElement], ['img', target.HTMLImageElement], ['span', target.HTMLSpanElement], ['style', target.HTMLStyleElement], ]), nameByConstructor: new Map(), }) const initElement = (name, Class) => { const target = Object.setPrototypeOf(new EventTarget(), Class.prototype) INTERNALS$3.set(target, { attributes: {}, localName: name, ownerDocument: document, shadowRoot: null, shadowInit: null, }) return target } document.body = initElement('body', target.HTMLBodyElement) document.head = initElement('head', target.HTMLHeadElement) document.documentElement = initElement('html', target.HTMLHtmlElement) } class HTMLCanvasElement extends HTMLElement { get height() { return internalsOf(this, 'HTMLCanvasElement', 'height').height } set height(value) { internalsOf(this, 'HTMLCanvasElement', 'height').height = Number(value) || 0 } get width() { return internalsOf(this, 'HTMLCanvasElement', 'width').width } set width(value) { internalsOf(this, 'HTMLCanvasElement', 'width').width = Number(value) || 0 } captureStream() { return null } getContext(contextType) { const internals = internalsOf(this, 'HTMLCanvasElement', 'getContext') switch (contextType) { case '2d': if (internals.renderingContext2D) return internals.renderingContext2D internals.renderingContext2D = __createCanvasRenderingContext2D(this) return internals.renderingContext2D default: return null } } toBlob() {} toDataURL() {} transferControlToOffscreen() {} } allowStringTag(HTMLCanvasElement) class HTMLImageElement extends HTMLElement { get src() { return internalsOf(this, 'HTMLImageElement', 'src').src } set src(value) { const internals = internalsOf(this, 'HTMLImageElement', 'src') internals.src = String(value) } } allowStringTag(HTMLImageElement) function Image() { // @ts-ignore INTERNALS$3.set(this, { attributes: {}, localName: 'img', innerHTML: '', shadowRoot: null, shadowInit: null, }) } Image.prototype = HTMLImageElement.prototype class IntersectionObserver { disconnect() {} observe() {} takeRecords() { return [] } unobserve() {} } class MutationObserver { disconnect() {} observe() {} takeRecords() { return [] } unobserve() {} } class ResizeObserver { disconnect() {} observe() {} takeRecords() { return [] } unobserve() {} } allowStringTag(MutationObserver) allowStringTag(IntersectionObserver) allowStringTag(ResizeObserver) class MediaQueryList extends EventTarget { get matches() { return internalsOf(this, 'MediaQueryList', 'matches').matches } get media() { return internalsOf(this, 'MediaQueryList', 'media').media } } allowStringTag(MediaQueryList) const initMediaQueryList = (target, exclude) => { if (exclude.has('MediaQueryList') || exclude.has('matchMedia')) return const EventTarget = target.EventTarget || globalThis.EventTarget const MediaQueryList = target.MediaQueryList || globalThis.MediaQueryList target.matchMedia = function matchMedia(media) { const mql = Object.setPrototypeOf( new EventTarget(), MediaQueryList.prototype ) INTERNALS$3.set(mql, { matches: false, media, }) return mql } } class OffscreenCanvas extends EventTarget { constructor(width, height) { super() if (arguments.length < 2) throw new TypeError( `Failed to construct 'OffscreenCanvas': 2 arguments required.` ) width = Number(width) || 0 height = Number(height) || 0 INTERNALS$3.set(this, { width, height }) } get height() { return internalsOf(this, 'OffscreenCanvas', 'height').height } set height(value) { internalsOf(this, 'OffscreenCanvas', 'height').height = Number(value) || 0 } get width() { return internalsOf(this, 'OffscreenCanvas', 'width').width } set width(value) { internalsOf(this, 'OffscreenCanvas', 'width').width = Number(value) || 0 } getContext(contextType) { const internals = internalsOf(this, 'HTMLCanvasElement', 'getContext') switch (contextType) { case '2d': if (internals.renderingContext2D) return internals.renderingContext2D internals.renderingContext2D = __createCanvasRenderingContext2D(this) return internals.renderingContext2D default: return null } } convertToBlob(options) { options = Object(options) Number(options.quality) || 0 const type = getImageType(String(options.type).trim().toLowerCase()) return Promise.resolve(new Blob([], { type })) } } allowStringTag(OffscreenCanvas) const getImageType = (type) => type === 'image/avif' || type === 'image/jpeg' || type === 'image/png' || type === 'image/webp' ? type : 'image/png' class Storage { clear() { internalsOf(this, 'Storage', 'clear').storage.clear() } getItem(key) { return getStringOrNull( internalsOf(this, 'Storage', 'getItem').storage.get(String(key)) ) } key(index) { return getStringOrNull( [...internalsOf(this, 'Storage', 'key').storage.keys()][ Number(index) || 0 ] ) } removeItem(key) { internalsOf(this, 'Storage', 'getItem').storage.delete(String(key)) } setItem(key, value) { internalsOf(this, 'Storage', 'getItem').storage.set( String(key), String(value) ) } get length() { return internalsOf(this, 'Storage', 'size').storage.size } } const getStringOrNull = (value) => (typeof value === 'string' ? value : null) const initStorage = (target, exclude) => { if (exclude.has('Storage') || exclude.has('localStorage')) return target.localStorage = Object.create(Storage.prototype) const storageInternals = new Map() INTERNALS$3.set(target.localStorage, { storage: storageInternals, }) } class Window extends EventTarget { get self() { return this } get top() { return this } get window() { return this } get innerHeight() { return 0 } get innerWidth() { return 0 } get scrollX() { return 0 } get scrollY() { return 0 } } allowStringTag(Window) const initWindow = (target, exclude) => { if (exclude.has('Window') || exclude.has('window')) return target.window = target } function alert(...messages) { console.log(...messages) } const hasOwn = { hasOwn(instance, property) { return __object_hasOwnProperty(instance, property) }, }.hasOwn const initObject = (target, exclude) => { if (exclude.has('Object') || exclude.has('object') || exclude.has('hasOwn')) return const Class = target.Object || globalThis.Object Object.defineProperty(Class, 'hasOwn', { value: hasOwn, writable: true, enumerable: false, configurable: true, }) } const any = { async any(iterable) { return Promise.all( [...iterable].map((promise) => { return new Promise((resolve, reject) => Promise.resolve(promise).then(reject, resolve) ) }) ).then( (errors) => Promise.reject(errors), (value) => Promise.resolve(value) ) }, }.any const initPromise = (target, exclude) => { if (exclude.has('Promise') || exclude.has('any')) return const Class = target.Promise || globalThis.Promise if (!Class.any) Object.defineProperty(Class, 'any', { value: any, writable: true, enumerable: false, configurable: true, }) } const at = { at(index) { index = Math.trunc(index) || 0 if (index < 0) index += this.length if (index < 0 || index >= this.length) return undefined return this[index] }, }.at const initRelativeIndexingMethod = (target, exclude) => { if (exclude.has('at')) return const Classes = [] if (!exclude.has('TypedArray')) Classes.push( Object.getPrototypeOf(target.Int8Array || globalThis.Int8Array) ) if (!exclude.has('Array')) Classes.push(target.Array || globalThis.Array) if (!exclude.has('String')) Classes.push(target.String || globalThis.String) for (const Class of Classes) { if (!Class.prototype.at) Object.defineProperty(Class.prototype, 'at', { value: at, writable: true, enumerable: false, configurable: true, }) } } const replaceAll = { replaceAll(searchValue, replaceValue) { return __object_isPrototypeOf(RegExp.prototype, searchValue) ? this.replace(searchValue, replaceValue) : this.replace( new RegExp(__string_escapeRegExp(searchValue), 'g'), replaceValue ) }, }.replaceAll const initString = (target, exclude) => { if (exclude.has('String') || exclude.has('replaceAll')) return const Class = target.String || globalThis.String if (!Class.prototype.replaceAll) Object.defineProperty(Class.prototype, 'replaceAll', { value: replaceAll, writable: true, enumerable: false, configurable: true, }) } const exclusionsForHTMLElement = [ 'CustomElementsRegistry', 'HTMLElement', 'HTMLBodyElement', 'HTMLCanvasElement', 'HTMLDivElement', 'HTMLHeadElement', 'HTMLHtmlElement', 'HTMLImageElement', 'HTMLStyleElement', 'HTMLTemplateElement', 'HTMLUnknownElement', 'Image', ] const exclusionsForElement = ['Element', ...exclusionsForHTMLElement] const exclusionsForDocument = [ 'CustomElementsRegistry', 'Document', 'HTMLDocument', 'document', 'customElements', ] const exclusionsForNode = [ 'Node', 'DocumentFragment', 'ShadowRoot', ...exclusionsForDocument, ...exclusionsForElement, ] const exclusionsForEventTarget = [ 'AbortSignal', 'Event', 'CustomEvent', 'EventTarget', 'OffscreenCanvas', 'MediaQueryList', 'Window', ...exclusionsForNode, ] const exclusionsForEvent = [ 'AbortSignal', 'Event', 'CustomEvent', 'EventTarget', 'MediaQueryList', 'OffscreenCanvas', 'Window', ...exclusionsForNode, ] const exclusions = { 'Blob+': ['Blob', 'File'], 'Document+': exclusionsForDocument, 'Element+': exclusionsForElement, 'Event+': exclusionsForEvent, 'EventTarget+': exclusionsForEventTarget, 'HTMLElement+': exclusionsForHTMLElement, 'Node+': exclusionsForNode, 'StyleSheet+': ['StyleSheet', 'CSSStyleSheet'], } const inheritence = { CSSStyleSheet: 'StyleSheet', CustomEvent: 'Event', DOMException: 'Error', Document: 'Node', DocumentFragment: 'Node', Element: 'Node', File: 'Blob', HTMLDocument: 'Document', HTMLElement: 'Element', HTMLBodyElement: 'HTMLElement', HTMLCanvasElement: 'HTMLElement', HTMLDivElement: 'HTMLElement', HTMLHeadElement: 'HTMLElement', HTMLHtmlElement: 'HTMLElement', HTMLImageElement: 'HTMLElement', HTMLSpanElement: 'HTMLElement', HTMLStyleElement: 'HTMLElement', HTMLTemplateElement: 'HTMLElement', HTMLUnknownElement: 'HTMLElement', Image: 'HTMLElement', MediaQueryList: 'EventTarget', Node: 'EventTarget', OffscreenCanvas: 'EventTarget', ShadowRoot: 'DocumentFragment', Window: 'EventTarget', } const polyfill = (target, options) => { const webAPIs = { AbortController, AbortSignal, Blob, ByteLengthQueuingStrategy, CanvasRenderingContext2D, CharacterData, Comment, CountQueuingStrategy, CSSStyleSheet, CustomElementRegistry, CustomEvent, Document, DocumentFragment, DOMException, Element, Event, EventTarget, File, FormData, HTMLDocument, HTMLElement, HTMLBodyElement, HTMLCanvasElement, HTMLDivElement, HTMLHeadElement, HTMLHtmlElement, HTMLImageElement, HTMLSpanElement, HTMLStyleElement, HTMLTemplateElement, HTMLUnknownElement, Headers, IntersectionObserver, Image, ImageData, MediaQueryList, MutationObserver, Node, NodeFilter: NodeFilter$1, NodeIterator: NodeIterator$1, OffscreenCanvas, ReadableByteStreamController, ReadableStream, ReadableStreamBYOBReader, ReadableStreamBYOBRequest, ReadableStreamDefaultController, ReadableStreamDefaultReader, Request, ResizeObserver, Response, ShadowRoot, Storage, StyleSheet, Text, TransformStream, TreeWalker, URLPattern: U, WritableStream, WritableStreamDefaultController, WritableStreamDefaultWriter, Window, alert, atob, btoa, cancelAnimationFrame, cancelIdleCallback, clearTimeout, fetch, requestAnimationFrame, requestIdleCallback, setTimeout, structuredClone, } // initialize exclude options const excludeOptions = new Set( typeof Object(options).exclude === 'string' ? String(Object(options).exclude).trim().split(/\s+/) : Array.isArray(Object(options).exclude) ? Object(options).exclude.reduce( (array, entry) => array.splice( array.length, 0, ...(typeof entry === 'string' ? entry.trim().split(/\s+/) : []) ) && array, [] ) : [] ) // expand exclude options using exclusion shorthands for (const excludeOption of excludeOptions) { if (excludeOption in exclusions) { for (const exclusion of exclusions[excludeOption]) { excludeOptions.add(exclusion) } } } // apply each WebAPI for (const name of Object.keys(webAPIs)) { // skip WebAPIs that are excluded if (excludeOptions.has(name)) continue // skip WebAPIs that are built-in if (Object.hasOwnProperty.call(target, name)) continue // define WebAPIs on the target Object.defineProperty(target, name, { configurable: true, enumerable: true, writable: true, value: webAPIs[name], }) } // ensure WebAPIs correctly inherit other WebAPIs for (const name of Object.keys(webAPIs)) { // skip WebAPIs that are excluded if (excludeOptions.has(name)) continue // skip WebAPIs that do not extend other WebAPIs if (!Object.hasOwnProperty.call(inheritence, name)) continue const Class = target[name] const Super = target[inheritence[name]] // skip WebAPIs that are not available if (!Class || !Super) continue // skip WebAPIs that are already inherited correctly if (Object.getPrototypeOf(Class.prototype) === Super.prototype) continue // define WebAPIs inheritence Object.setPrototypeOf(Class.prototype, Super.prototype) } if ( !excludeOptions.has('HTMLDocument') && !excludeOptions.has('HTMLElement') ) { initDocument(target, excludeOptions) if (!excludeOptions.has('CustomElementRegistry')) { initCustomElementRegistry(target, excludeOptions) } } initObject(target, excludeOptions) initMediaQueryList(target, excludeOptions) initPromise(target, excludeOptions) initRelativeIndexingMethod(target, excludeOptions) initStorage(target, excludeOptions) initString(target, excludeOptions) initWindow(target, excludeOptions) return target } polyfill.internals = (target, name) => { const init = { CustomElementRegistry: initCustomElementRegistry, Document: initDocument, MediaQueryList: initMediaQueryList, Object: initObject, Promise: initPromise, RelativeIndexingMethod: initRelativeIndexingMethod, Storage: initStorage, String: initString, Window: initWindow, } init[name](target, new Set()) return target } let s = 0 const S = { START_BOUNDARY: s++, HEADER_FIELD_START: s++, HEADER_FIELD: s++, HEADER_VALUE_START: s++, HEADER_VALUE: s++, HEADER_VALUE_ALMOST_DONE: s++, HEADERS_ALMOST_DONE: s++, PART_DATA_START: s++, PART_DATA: s++, END: s++, } let f = 1 const F = { PART_BOUNDARY: f, LAST_BOUNDARY: (f *= 2), } const LF = 10 const CR = 13 const SPACE = 32 const HYPHEN = 45 const COLON = 58 const A = 97 const Z = 122 const lower = (c) => c | 0x20 const noop = () => {} class MultipartParser { /** * @param {string} boundary */ constructor(boundary) { this.index = 0 this.flags = 0 this.onHeaderEnd = noop this.onHeaderField = noop this.onHeadersEnd = noop this.onHeaderValue = noop this.onPartBegin = noop this.onPartData = noop this.onPartEnd = noop this.boundaryChars = {} boundary = '\r\n--' + boundary const ui8a = new Uint8Array(boundary.length) for (let i = 0; i < boundary.length; i++) { ui8a[i] = boundary.charCodeAt(i) this.boundaryChars[ui8a[i]] = true } this.boundary = ui8a this.lookbehind = new Uint8Array(this.boundary.length + 8) this.state = S.START_BOUNDARY } /** * @param {Uint8Array} data */ write(data) { let i = 0 const length_ = data.length let previousIndex = this.index let { lookbehind, boundary, boundaryChars, index, state, flags } = this const boundaryLength = this.boundary.length const boundaryEnd = boundaryLength - 1 const bufferLength = data.length let c let cl const mark = (name) => { this[name + 'Mark'] = i } const clear = (name) => { delete this[name + 'Mark'] } const callback = (callbackSymbol, start, end, ui8a) => { if (start === undefined || start !== end) { this[callbackSymbol](ui8a && ui8a.subarray(start, end)) } } const dataCallback = (name, clear) => { const markSymbol = name + 'Mark' if (!(markSymbol in this)) { return } if (clear) { callback(name, this[markSymbol], i, data) delete this[markSymbol] } else { callback(name, this[markSymbol], data.length, data) this[markSymbol] = 0 } } for (i = 0; i < length_; i++) { c = data[i] switch (state) { case S.START_BOUNDARY: if (index === boundary.length - 2) { if (c === HYPHEN) { flags |= F.LAST_BOUNDARY } else if (c !== CR) { return } index++ break } else if (index - 1 === boundary.length - 2) { if (flags & F.LAST_BOUNDARY && c === HYPHEN) { state = S.END flags = 0 } else if (!(flags & F.LAST_BOUNDARY) && c === LF) { index = 0 callback('onPartBegin') state = S.HEADER_FIELD_START } else { return } break } if (c !== boundary[index + 2]) { index = -2 } if (c === boundary[index + 2]) { index++ } break case S.HEADER_FIELD_START: state = S.HEADER_FIELD mark('onHeaderField') index = 0 // falls through case S.HEADER_FIELD: if (c === CR) { clear('onHeaderField') state = S.HEADERS_ALMOST_DONE break } index++ if (c === HYPHEN) { break } if (c === COLON) { if (index === 1) { // empty header field return } dataCallback('onHeaderField', true) state = S.HEADER_VALUE_START break } cl = lower(c) if (cl < A || cl > Z) { return } break case S.HEADER_VALUE_START: if (c === SPACE) { break } mark('onHeaderValue') state = S.HEADER_VALUE // falls through case S.HEADER_VALUE: if (c === CR) { dataCallback('onHeaderValue', true) callback('onHeaderEnd') state = S.HEADER_VALUE_ALMOST_DONE } break case S.HEADER_VALUE_ALMOST_DONE: if (c !== LF) { return } state = S.HEADER_FIELD_START break case S.HEADERS_ALMOST_DONE: if (c !== LF) { return } callback('onHeadersEnd') state = S.PART_DATA_START break case S.PART_DATA_START: state = S.PART_DATA mark('onPartData') // falls through case S.PART_DATA: previousIndex = index if (index === 0) { // boyer-moore derrived algorithm to safely skip non-boundary data i += boundaryEnd while (i < bufferLength && !(data[i] in boundaryChars)) { i += boundaryLength } i -= boundaryEnd c = data[i] } if (index < boundary.length) { if (boundary[index] === c) { if (index === 0) { dataCallback('onPartData', true) } index++ } else { index = 0 } } else if (index === boundary.length) { index++ if (c === CR) { // CR = part boundary flags |= F.PART_BOUNDARY } else if (c === HYPHEN) { // HYPHEN = end boundary flags |= F.LAST_BOUNDARY } else { index = 0 } } else if (index - 1 === boundary.length) { if (flags & F.PART_BOUNDARY) { index = 0 if (c === LF) { // unset the PART_BOUNDARY flag flags &= ~F.PART_BOUNDARY callback('onPartEnd') callback('onPartBegin') state = S.HEADER_FIELD_START break } } else if (flags & F.LAST_BOUNDARY) { if (c === HYPHEN) { callback('onPartEnd') state = S.END flags = 0 } else { index = 0 } } else { index = 0 } } if (index > 0) { // when matching a possible boundary, keep a lookbehind reference // in case it turns out to be a false lead lookbehind[index - 1] = c } else if (previousIndex > 0) { // if our boundary turned out to be rubbish, the captured lookbehind // belongs to partData const _lookbehind = new Uint8Array( lookbehind.buffer, lookbehind.byteOffset, lookbehind.byteLength ) callback('onPartData', 0, previousIndex, _lookbehind) previousIndex = 0 mark('onPartData') // reconsider the current character even so it interrupted the sequence // it could be the beginning of a new sequence i-- } break case S.END: break default: throw new Error(`Unexpected state entered: ${state}`) } } dataCallback('onHeaderField') dataCallback('onHeaderValue') dataCallback('onPartData') // Update properties for the next call this.index = index this.state = state this.flags = flags } end() { if ( (this.state === S.HEADER_FIELD_START && this.index === 0) || (this.state === S.PART_DATA && this.index === this.boundary.length) ) { this.onPartEnd() } else if (this.state !== S.END) { throw new Error('MultipartParser.end(): stream ended unexpectedly') } } } function _fileName(headerValue) { // matches either a quoted-string or a token (RFC 2616 section 19.5.1) const m = headerValue.match( /\bfilename=("(.*?)"|([^()<>@,;:\\"/[\]?={}\s\t]+))($|;\s)/i ) if (!m) { return } const match = m[2] || m[3] || '' let filename = match.slice(match.lastIndexOf('\\') + 1) filename = filename.replace(/%22/g, '"') filename = filename.replace(/&#(\d{4});/g, (m, code) => { return String.fromCharCode(code) }) return filename } async function toFormData(Body, ct) { if (!/multipart/i.test(ct)) { throw new TypeError('Failed to fetch') } const m = ct.match(/boundary=(?:"([^"]+)"|([^;]+))/i) if (!m) { throw new TypeError('no or bad content-type header, no multipart boundary') } const parser = new MultipartParser(m[1] || m[2]) let headerField let headerValue let entryValue let entryName let contentType let filename const entryChunks = [] const formData = new FormData() const onPartData = (ui8a) => { entryValue += decoder.decode(ui8a, { stream: true }) } const appendToFile = (ui8a) => { entryChunks.push(ui8a) } const appendFileToFormData = () => { const file = new File(entryChunks, filename, { type: contentType }) formData.append(entryName, file) } const appendEntryToFormData = () => { formData.append(entryName, entryValue) } const decoder = new TextDecoder('utf-8') decoder.decode() parser.onPartBegin = function () { parser.onPartData = onPartData parser.onPartEnd = appendEntryToFormData headerField = '' headerValue = '' entryValue = '' entryName = '' contentType = '' filename = null entryChunks.length = 0 } parser.onHeaderField = function (ui8a) { headerField += decoder.decode(ui8a, { stream: true }) } parser.onHeaderValue = function (ui8a) { headerValue += decoder.decode(ui8a, { stream: true }) } parser.onHeaderEnd = function () { headerValue += decoder.decode() headerField = headerField.toLowerCase() if (headerField === 'content-disposition') { // matches either a quoted-string or a token (RFC 2616 section 19.5.1) const m = headerValue.match( /\bname=("([^"]*)"|([^()<>@,;:\\"/[\]?={}\s\t]+))/i ) if (m) { entryName = m[2] || m[3] || '' } filename = _fileName(headerValue) if (filename) { parser.onPartData = appendToFile parser.onPartEnd = appendFileToFormData } } else if (headerField === 'content-type') { contentType = headerValue } headerValue = '' headerField = '' } for await (const chunk of Body) { parser.write(chunk) } parser.end() return formData } var multipartParser = /*#__PURE__*/ Object.freeze({ __proto__: null, toFormData: toFormData, }) export { AbortController, AbortSignal, Blob, ByteLengthQueuingStrategy, CSSStyleSheet, CanvasRenderingContext2D, CharacterData, Comment, CountQueuingStrategy, CustomElementRegistry, CustomEvent, DOMException, Document, DocumentFragment, Element, Event, EventTarget, File, FormData, HTMLBodyElement, HTMLCanvasElement, HTMLDivElement, HTMLDocument, HTMLElement, HTMLHeadElement, HTMLHtmlElement, HTMLImageElement, HTMLSpanElement, HTMLStyleElement, HTMLTemplateElement, HTMLUnknownElement, Headers, Image, ImageData, IntersectionObserver, MediaQueryList, MutationObserver, Node, NodeFilter$1 as NodeFilter, NodeIterator$1 as NodeIterator, OffscreenCanvas, ReadableByteStreamController, ReadableStream, ReadableStreamBYOBReader, ReadableStreamBYOBRequest, ReadableStreamDefaultController, ReadableStreamDefaultReader, Request, ResizeObserver, Response, ShadowRoot, StyleSheet, Text, TransformStream, TreeWalker, U as URLPattern, Window, WritableStream, WritableStreamDefaultController, WritableStreamDefaultWriter, alert, atob, btoa, cancelAnimationFrame, cancelIdleCallback, clearTimeout, fetch, pathToPosix, polyfill, requestAnimationFrame, requestIdleCallback, setTimeout, structuredClone, } //# sourceMappingURL=mod.js.map