leStackInternalField(this, @disposableStackFieldState) === @DisposableStackStateDisposed)
        throw new @ReferenceError("DisposableStack.prototype.adopt requires that |this| be a pending DisposableStack object");

    if (!@isCallable(onDispose))
        @throwTypeError("DisposableStack.prototype.adopt requires that onDispose argument be a callable");

    var closure = () => { onDispose.@call(@undefined, value); }
    @addDisposableResource(@getDisposableStackInternalField(this, @disposableStackFieldCapability), @undefined,  false, closure);

    return value;
})
(function (string, index, unicode)
{
    //
    "use strict";

    if (!unicode)
        return index + 1;

    if (index + 1 >= string.length)
        return index + 1;

    var first = string.@charCodeAt(index);
    if (first < 0xD800 || first > 0xDBFF)
        return index + 1;

    var second = string.@charCodeAt(index + 1);
    if (second < 0xDC00 || second > 0xDFFF)
        return index + 1;

    return index + 2;
})
(function (iterable)
{
    "use strict";

    if (this !== @Promise)
        return @tailCallForwardArguments(@promiseAllSlow, this);

    var promise = @newPromise();
    var values = [];
    var remainingElementsCountObj = { value: 1 };
    var index = 0;
    var onRejected;

    try {
        var promiseResolve = this.resolve;
        if (!@isCallable(promiseResolve))
            @throwTypeError("Promise resolve is not a function");

        for (var value of iterable) {
            @putByValDirect(values, index, @undefined);
            var nextPromise = promiseResolve.@call(this, value);
            ++remainingElementsCountObj.value;
            var then = nextPromise.then;
            var context = @promiseAllContextCreate(promise, values, remainingElementsCountObj, index);
            if (@isPromise(nextPromise) && then === @defaultPromiseThen) {
                var constructor = @speciesConstructor(nextPromise, @Promise);
                var promiseOrCapability;
                if (constructor !== @Promise)
                    promiseOrCapability = @newPromiseCapabilitySlow(constructor);
                @performPromiseThen(nextPromise, @promiseAllOnFulfilled, @promiseOnRejectedWithContext, promiseOrCapability, context);
            } else {
                if (!onRejected)
                    onRejected = @promiseNewOnRejected(promise);
                then.@call(nextPromise, @promiseAllNewResolveElement(context, index), onRejected);
            }
            ++index;
        }

        if (!--remainingElementsCountObj.value)
            @resolvePromiseWithFirstResolvingFunctionCallCheck(promise, values);
    } catch (error) {
        @rejectPromiseWithFirstResolvingFunctionCallCheck(promise, error);
    }

    return promise;
})
(function (iterable)
{
    "use strict";

    if (!@isObject(this))
        @throwTypeError("|this| is not an object");

    var promiseCapability = @newPromiseCapability(this);
    var resolve = promiseCapability.resolve;
    var reject = promiseCapability.reject;
    var promise = promiseCapability.promise;

    var values = [];
    var remainingElementsCount = 1;
    var index = 0;

    try {
        var promiseResolve = this.resolve;
        if (!@isCallable(promiseResolve))
            @throwTypeError("Promise resolve is not a function");

        for (var value of iterable) {
            @putByValDirect(values, index, @undefined);
            var nextPromise = promiseResolve.@call(this, value);
            ++remainingElementsCount;
            let currentIndex = index++;
            nextPromise.then(
                (value) => {
                    if (currentIndex < 0)
                        return @undefined;

                    @putByValDirect(values, currentIndex, {
                        status: "fulfilled",
                        value
                    });
                    currentIndex = -1;

                    --remainingElementsCount;
                    if (remainingElementsCount === 0)
                        return resolve.@call(@undefined, values);
                    return @undefined;
                },
                (reason) => {
                    if (currentIndex < 0)
                        return @undefined;

                    @putByValDirect(values, currentIndex, {
                        status: "rejected",
                        reason
                    });
                    currentIndex = -1;

                    --remainingElementsCount;
                    if (remainingElementsCount === 0)
                        return resolve.@call(@undefined, values);
                    return @undefined;
                }
            );
        }

        --remainingElementsCount;
        if (remainingElementsCount === 0)
            resolve.@call(@undefined, values);
    } catch (error) {
        reject.@call(@undefined, error);
    }

    return promise;
})
(function (url)
{
    "use strict";
    return @createHTML("String.prototype.link", this, "a", "name", url)
})
(function (iterable)
{
    "use strict";

    if (!@isObject(this))
        @throwTypeError("|this| is not an object");

    var promiseCapability = @newPromiseCapability(this);
    var resolve = promiseCapability.resolve;
    var reject = promiseCapability.reject;
    var promise = promiseCapability.promise;

    var errors = [];
    var remainingElementsCount = 1;
    var index = 0;

    try {
        var promiseResolve = this.resolve;
        if (!@isCallable(promiseResolve))
            @throwTypeError("Promise resolve is not a function");

        for (var value of iterable) {
            @putByValDirect(errors, index, @undefined);
            var nextPromise = promiseResolve.@call(this, value);
            var then = nextPromise.then;
            let currentIndex = index++;
            ++remainingElementsCount;

            //
            var onRejected = (0, (reason) => {
              if (currentIndex < 0)
                return @undefined;

              @putByValDirect(errors, currentIndex, reason);
              currentIndex = -1;

              if (!--remainingElementsCount)
                reject.@call(@undefined, new @AggregateError(errors));

              return @undefined;
            });
            if (@isPromise(nextPromise) && then === @defaultPromiseThen)
                @performPromiseThen(nextPromise, resolve, onRejected, @undefined,  promise);
            else
                then.@call(nextPromise, resolve, onRejected);
        }

        --remainingElementsCount;
        if (remainingElementsCount === 0)
            throw new @AggregateError(errors);
    } catch (error) {
        reject.@call(@undefined, error);
    }

    return promise;
})
(function (thisValue, argumentValues)
{
    "use strict";

    return this.@apply(thisValue, argumentValues);
})
(function (target, thisArgument, argumentsList)
{
    "use strict";

    if (!@isCallable(target))
        @throwTypeError("Reflect.apply requires the first argument be a function");

    if (!@isObject(argumentsList))
        @throwTypeError("Reflect.apply requires the third argument be an object");

    return target.@apply(thisArgument, argumentsList);
})
(function (array, kind)
{
    "use strict";
    var done = true;
    var value;

    var index = @getArrayIteratorInternalField(this, @arrayIteratorFieldIndex);
    if (index !== -1) {
        var length = @isTypedArrayView(array) ? @typedArrayLength(array) : @toLength(array.length);
        if (index < length) {
            @putArrayIteratorInternalField(this, @arrayIteratorFieldIndex, index + 1);
            done = false;
            if (kind === @iterationKindKey)
                value = index;
            else {
                value = array[index];
                if (kind === @iterationKindEntries)
                    value = [index, value];
            }
        } else
            @putArrayIteratorInternalField(this, @arrayIteratorFieldIndex, -1);
    }

    return { value, done };
})
(function ()
{
    'use strict';

    var promiseCapability = @newPromiseCapability(@Promise);
    var returnMethod;
    try {
        returnMethod = this.return;
    } catch (e) {
        @rejectPromiseWithFirstResolvingFunctionCallCheck(promiseCapability.promise, e);
        return promiseCapability.promise;
    }

    if (returnMethod === @undefined)
        promiseCapability.resolve.@call();
    else {
        var result;
        try {
            result = returnMethod.@call(this);
        } catch (e) {
            @rejectPromiseWithFirstResolvingFunctionCallCheck(promiseCapability.promise, e);
            return promiseCapability.promise;
        }
        var resultWrapper;
        try {
            resultWrapper = @promiseResolve(@Promise, result);
        } catch (e) {
            @rejectPromiseWithFirstResolvingFunctionCallCheck(promiseCapability.promise, e);
            return promiseCapability.promise;
        }
        var onFulfilled = () => { return @undefined; };
        @performPromiseThen(resultWrapper, onFulfilled, @undefined, promiseCapability, @undefined);
    }

    return promiseCapability.promise;
})
(function (result, context)
{
    "use strict";

    @assert(@isPromise(context.@promise));

    return @resolvePromiseWithFirstResolvingFunctionCallCheck(context.@promise, { value: result, done: false });
})
(function (result, context)
{
    "use strict";

    @assert(@isPromise(context.@promise));

    return @resolvePromiseWithFirstResolvingFunctionCallCheck(context.@promise, { value: result, done: true });
})
(function (error, context)
{
    "use strict";

    var syncIterator = context.@syncIterator;
    var promise = context.@promise;

    @assert(@isObject(syncIterator) || syncIterator === @undefined);
    @assert(@isPromise(promise));

    if (syncIterator !== @undefined) {
        var returnMethod;
        try {
            returnMethod = syncIterator.return;
        } catch (e) {
            return @rejectPromiseWithFirstResolvingFunctionCallCheck(promise, e);
        }
        returnMethod.@call(syncIterator);
    }

    return @rejectPromiseWithFirstResolvingFunctionCallCheck(promise, error);
})
(function (generator, sentValue, resumeMode)
{
    "use strict";

    var state = @getGeneratorInternalField(generator, @generatorFieldState);

    try {
        @putGeneratorInternalField(generator, @generatorFieldState, @GeneratorStateExecuting);
        var value = @getGeneratorInternalField(generator, @generatorFieldNext).@call(@getGeneratorInternalField(generator, @generatorFieldThis), generator, state, sentValue, resumeMode, @getGeneratorInternalField(generator, @generatorFieldFrame));
        if (@getGeneratorInternalField(generator, @generatorFieldState) === @GeneratorStateExecuting)
            return @resolvePromiseWithFirstResolvingFunctionCallCheck(@getGeneratorInternalField(generator, @generatorFieldContext), value);
    } catch (error) {
        return @rejectPromiseWithFirstResolvingFunctionCallCheck(@getGeneratorInternalField(generator, @generatorFieldContext), error);
    }

    return @resolveWithoutPromiseForAsyncAwait(value, @asyncFunctionResumeOnFulfilled, @asyncFunctionResumeOnRejected, generator);
})
(function (value, generator)
{
    "use strict";

    return @asyncFunctionResume(generator, value, @GeneratorResumeModeNormal);
})
(function (error, generator)
{
    "use strict";

    return @asyncFunctionResume(generator, error, @GeneratorResumeModeThrow);
})
(function (generator, value, resumeMode)
{
    "use strict";

    var promise = @newPromise();
    if (!@isAsyncGenerator(generator)) {
        @rejectPromiseWithFirstResolvingFunctionCallCheck(promise, @makeTypeError('|this| should be an async generator'));
        return promise;
    }

    @asyncGeneratorQueueEnqueue(generator, {resumeMode, value, promise, next: null});

    if (!@isExecutionState(generator))
        @asyncGeneratorResumeNext(generator);

    return promise;
})
(function (generator)
{
    "use strict";

    @assert(!@asyncGeneratorQueueIsEmpty(generator), "Async genetator's Queue is an empty List.");

    var result = @getAsyncGeneratorInternalField(generator, @asyncGeneratorFieldQueueFirst);

    var updatedFirst = @getByIdDirect(result, "next");
    @putAsyncGeneratorInternalField(generator, @asyncGeneratorFieldQueueFirst, updatedFirst);

    if (updatedFirst === null)
        @putAsyncGeneratorInternalField(generator, @asyncGeneratorFieldQueueLast, null);

    return result;
})
(function (generator, item)
{
    "use strict";

    @assert(@getByIdDirect(item, "next") === null);

    if (@getAsyncGeneratorInternalField(generator, @asyncGeneratorFieldQueueFirst) === null) {
        @assert(@getAsyncGeneratorInternalField(generator, @asyncGeneratorFieldQueueLast) === null);

        @putAsyncGeneratorInternalField(generator, @asyncGeneratorFieldQueueFirst, item);
        @putAsyncGeneratorInternalField(generator, @asyncGeneratorFieldQueueLast, item);
    } else {
        var last = @getAsyncGeneratorInternalField(generator, @asyncGeneratorFieldQueueLast);
        @putByIdDirect(last, "next", item);
        @putAsyncGeneratorInternalField(generator, @asyncGeneratorFieldQueueLast, item);
    }
})
(function (generator)
{
    "use strict";

    return @getAsyncGeneratorInternalField(generator, @asyncGeneratorFieldQueueFirst) === null;
})
(function (generator, exception)
{
    "use strict";

    @assert(@isAsyncGenerator(generator), "Generator is not an AsyncGenerator instance.");

    var promise = @asyncGeneratorQueueDequeue(generator).promise;
    @assert(@isPromise(promise));
    @rejectPromiseWithFirstResolvingFunctionCallCheck(promise, exception);

    return @asyncGeneratorResumeNext(generator);
})
(function (generator, value, done)
{
    "use strict";

    @assert(@isAsyncGenerator(generator), "Generator is not an AsyncGenerator instance.");

    var promise = @asyncGeneratorQueueDequeue(generator).promise;
    @assert(@isPromise(promise));
    @resolvePromiseWithFirstResolvingFunctionCallCheck(promise, { value, done });

    return @asyncGeneratorResumeNext(generator);
})
(function (generator)
{
    "use strict";

    @assert(@isAsyncGenerator(generator), "Generator is not an AsyncGenerator instance.");

    var state = @getAsyncGeneratorInternalField(generator, @generatorFieldState);

    @assert(state !== @AsyncGeneratorStateExecuting, "Async generator should not be in executing state");

    if (state === @AsyncGeneratorStateAwaitingReturn)
        return;

    if (@asyncGeneratorQueueIsEmpty(generator))
        return;

    var next = @getAsyncGeneratorInternalField(generator, @asyncGeneratorFieldQueueFirst);

    if (next.resumeMode !== @GeneratorResumeModeNormal) {
        if (state === @AsyncGeneratorStateSuspendedStart) {
            @putAsyncGeneratorInternalField(generator, @generatorFieldState, @AsyncGeneratorStateCompleted);
            state = @AsyncGeneratorStateCompleted;
        }

        if (state === @AsyncGeneratorStateCompleted) {
            if (next.resumeMode === @GeneratorResumeModeReturn) {
                @putAsyncGeneratorInternalField(generator, @generatorFieldState, @AsyncGeneratorStateAwaitingReturn);
                @resolveWithoutPromiseForAsyncAwait(next.value, @asyncGeneratorResumeNextOnFulfilled, @asyncGeneratorResumeNextOnRejected, generator);
                return;
            }

            @assert(next.resumeMode === @GeneratorResumeModeThrow, "Async generator has wrong mode");

            return @asyncGeneratorReject(generator, next.value);;
        }
    } else if (state === @AsyncGeneratorStateCompleted)
        return @asyncGeneratorResolve(generator, @undefined, true);

    @assert(state === @AsyncGeneratorStateSuspendedStart || @isSuspendYieldState(generator), "Async generator has wrong state");

    @doAsyncGeneratorBodyCall(generator, next.value, next.resumeMode);
})
(function (result, generator)
{
    "use strict";

    @putAsyncGeneratorInternalField(generator, @generatorFieldState, @AsyncGeneratorStateCompleted);
    @asyncGeneratorResolve(generator, result, true);
})
(function (error, generator)
{
    "use strict";

    @putAsyncGeneratorInternalField(generator, @generatorFieldState, @AsyncGeneratorStateCompleted);
    @asyncGeneratorReject(generator, error);
})
(function (generator, value, resumeMode)
{
    "use strict";

    @putAsyncGeneratorInternalField(generator, @asyncGeneratorFieldSuspendReason, @AsyncGeneratorSuspendReasonAwait);
    @awaitValue(generator, value, @asyncGeneratorYieldAwaited);
})
(function (result, generator)
{
    "use strict";

    @putAsyncGeneratorInternalField(generator, @asyncGeneratorFieldSuspendReason, @AsyncGeneratorSuspendReasonYield);
    @asyncGeneratorResolve(generator, result, false);
})
(function (result, generator)
{
    "use strict";

    @doAsyncGeneratorBodyCall(generator, result, @GeneratorResumeModeThrow);
})
(async function (entry, fetcher, dependencies)
{
    "use strict";

    for (var i = 0, length = dependencies.length; i < length; ++i)
        await this.moduleEvaluation(dependencies[i], fetcher);

    var resumeMode = @GeneratorResumeModeNormal;
    while (true) {
        var awaitedValue = this.evaluate(entry.key, entry.module, fetcher, awaitedValue, resumeMode);
        if (@getAbstractModuleRecordInternalField(entry.module, @abstractModuleRecordFieldState) == @GeneratorStateExecuting)
            return;

        try {
            awaitedValue = await awaitedValue;
            resumeMode = @GeneratorResumeModeNormal;
        } catch (e) {
            awaitedValue = e;
            resumeMode = @GeneratorResumeModeThrow;
        }
    }
})
(function (index)
{
    "use strict";

    var array = @toObject(this, "Array.prototype.at requires that |this| not be null or undefined");
    var length = @toLength(array.length);

    var k = @toIntegerOrInfinity(index);
    if (k < 0)
        k += length;

    return (k >= 0 && k < length) ? array[k] : @undefined;
})
(function (index)
{
    "use strict";

    var length = @typedArrayLength(this);

    var k = @toIntegerOrInfinity(index);
    if (k < 0)
        k += length;

    return (k >= 0 && k < length) ? this[k] : @undefined;
})
(function (generator, value, onFulfilled)
{
    "use strict";

    @resolveWithoutPromiseForAsyncAwait(value, onFulfilled, @asyncGeneratorYieldOnRejected, generator);
})
(function ()
{
    "use strict";
    return @createHTML("String.prototype.big", this, "big", "", "");
})
(function ()
{
    "use strict";
    return @createHTML("String.prototype.blink", this, "blink", "", "");
})
(function ()
{
    "use strict";
    return @createHTML("String.prototype.bold", this, "b", "", "");
})
(function (map)
{
    "use strict";
    
    if (!@isMap(map))
        @throwTypeError("builtinMapIterable called with non-Map object.");

    //
    //
    //
    var iteratorFunction = map.@entries;

    return @wrappedIterator(iteratorFunction.@call(map));
})
(function (set)
{
    "use strict";
    
    if (!@isSet(set))
        @throwTypeError("builtinSetIterable called with non-Set object.");

    //
    //
    //
    var iteratorFunction = set.@values;
    
    return @wrappedIterator(iteratorFunction.@call(set));
})
(function (entry)
{
    "use strict";

    @setStateToMax(entry, @ModuleLink);
    entry.satisfy = (async () => {
        return entry;
    })();
})
(function (entry, depEntries, satisfyingEntries)
{
    "use strict";

    entry.isSatisfied = true;
    for (var i = 0, length = depEntries.length; i < length; ++i) {
        if (!depEntries[i].isSatisfied) {
            entry.isSatisfied = false;
            break;
        }
    }

    if (entry.isSatisfied)
        @cacheSatisfy(entry);
    else
        satisfyingEntries.@add(entry);
    return entry;
})
(function (thisArgument)
{
    "use strict";

    var argumentValues = [];
    //
    for (var i = 1; i < @argumentCount(); i++)
        @putByValDirect(argumentValues, i-1, arguments[i]);

    return this.@apply(thisArgument, argumentValues);
})
(function (onRejected)
{
    "use strict";

    return this.then(@undefined, onRejected);
})
(function (chunkSize)
{
    "use strict";

    if (!@isObject(this))
        @throwTypeError("Iterator.prototype.chunks requires that |this| be an Object.");

    var numChunkSize = @toNumber(chunkSize);
    if (numChunkSize !== numChunkSize)
        @throwRangeError("Iterator.prototype.chunks requires that first argument not be NaN.");

    var intChunkSize = @toIntegerOrInfinity(numChunkSize);
    if (intChunkSize < 1 || intChunkSize > @MAX_ARRAY_INDEX)
        @throwRangeError("Iterator.prototype.chunks requires that first argument be between 1 and 2**32 - 1.");

    var iterated = this;
    var iteratedNextMethod = this.next;

    var generator = (function*() {
        var buffer = [];

        for (;;) {
            var result = @iteratorGenericNext(iteratedNextMethod, iterated);
            if (result.done) {
                if (buffer.length)
                    yield buffer;
                return;
            }

            @arrayPush(buffer, result.value);

            if (buffer.length === intChunkSize) {
                @ifAbruptCloseIterator(iterated, (
                    yield buffer
                ));

                buffer = [];
            }
        }
    })();

    return @iteratorHelperCreate(generator, iterated);
})
(function (source) {
    "use strict";

    return @Promise.@resolve(source).@then(@webAssemblyCompileStreamingInternal);
})
(function ()
{
    "use strict";

    var argumentCount = @argumentCount();

    var openMethods = [];
    var iterables = [];
    for (var i = 0; i < argumentCount; ++i) {
        var iterable = arguments[i];
        if (!@isObject(iterable))
            @throwTypeError("Iterator.concat expects all arguments to be objects");

        var openMethod = iterable.@@iterator;
        if (!@isCallable(openMethod))
            @throwTypeError("Iterator.concat expects all arguments to be iterable");

        @arrayPush(openMethods, openMethod);
        @arrayPush(iterables, iterable);
    }

    var generator = (function*() {
        for (var i = 0; i < argumentCount; ++i) {
            var iterator = openMethods[i].@call(iterables[i]);
            if (!@isObject(iterator))
                @throwTypeError("Iterator.concat expects all arguments to be iterable");

            var nextMethod = iterator.next;

            for (;;) {
                var result = @iteratorGenericNext(nextMethod, iterator);
                if (result.done)
                    break;

                var value = result.value;
                @ifAbruptCloseIterator(iterator, (
                    yield value
                ));
            }
        }
    })();

    return @iteratorHelperCreate(generator, null);
})
(function (arg )
{
    "use strict";

    if (@isUndefinedOrNull(this))
        @throwTypeError("String.prototype.concat requires that |this| not be null or undefined");

    if (@argumentCount() === 1)
        return @toString(this) + @toString(arg);
    return @tailCallForwardArguments(@stringConcatSlowPath, this);
})
(function ()
{
    let array = new @Array(arguments.length);
    array.__proto__ = null;
    
    for (let i = 0; i < arguments.length; ++i)
        @arrayPush(array, arguments[i]);
    
    return array;
})
(function (syncIterator, nextMethod)
{
    "use strict";

    if (!@isObject(syncIterator))
        @throwTypeError('Only objects can be wrapped by async-from-sync wrapper');

    return @asyncFromSyncIteratorCreate(syncIterator, nextMethod);
})
(function (value, isAsync )
{
    'use strict';

    var method;
    if (@argumentCount() < 3) {
        if (@isUndefinedOrNull(value))
            value = @undefined;
        else {
            if (!@isObject(value))
                @throwTypeError("Disposable value must be an object");
            if (isAsync) {
                method = @getAsyncDisposableMethod(value);
                if (method === @undefined)
                    @throwTypeError("@@asyncDispose must not be an undefined");
            } else {
                method = value.@@dispose;
                if (!@isCallable(method))
                    @throwTypeError("@@dispose must be callable");
                if (@isUndefinedOrNull(method))
                    @throwTypeError("@@dispose must not be an undefined");
            }
        }
    } else {
        method = @argument(2);
        if (!@isCallable(method))
            @throwTypeError("Callback that is called on dispose must be callable");
    }

    return { value, method };
})
(function (func, string, tag, attribute, value)
{
    "use strict";
    if (@isUndefinedOrNull(string))
        @throwTypeError(`${func} requires that |this| not be null or undefined`);
    var S = @toString(string);
    var p1 = "<" + tag;
    if (attribute) {
        var V = @toString(value);
        var escapedV = V.@replaceUsingRegExp(/"/g, '&quot;');
        p1 = p1 + " " + @toString(attribute) + '="' + escapedV + '"'
    }
    var p2 = p1 + ">"
    var p3 = p2 + S;
    var p4 = p3 + "</" + tag + ">";
    return p4;
})
(function (InjectedScriptHost, inspectedGlobalObject, injectedScriptId)
{

function PrototypelessObjectBase() {}
PrototypelessObjectBase.prototype = null;

function toString(obj)
{
    return @String(obj);
}

function toStringDescription(obj)
{
    if (obj === 0 && 1 / obj < 0)
        return "-0";

    if (isBigInt(obj))
        return toString(obj) + "n";

    return toString(obj);
}

function isUInt32(obj)
{
    if (typeof obj === "number")
        return obj >>> 0 === obj && (obj > 0 || 1 / obj > 0);
    return "" + (obj >>> 0) === obj;
}

function isSymbol(value)
{
    return typeof value === "symbol";
}

function isBigInt(value)
{
    return typeof value === "bigint";
}

function isEmptyObject(object)
{
    for (let key in object)
        return false;
    return true;
}

function isDefined(value)
{
    return !!value || InjectedScriptHost.isHTMLAllCollection(value);
}

function isPrimitiveValue(value)
{
    switch (typeof value) {
    case "boolean":
    case "number":
    case "string":
        return true;
    case "undefined":
        return !InjectedScriptHost.isHTMLAllCollection(value);
    default:
        return false;
    }
}
    
function createIterableWithoutPrototypeFromArguments(argumentsObject) {
    let iteratorFunction = argumentsObject.@@iterator;
    return @wrappedIterator(iteratorFunction.@call(argumentsObject));
}

function max(a, b) {
    return a > b ? a : b;
}

//

let InjectedScript = class InjectedScript extends PrototypelessObjectBase
{
    constructor()
    {
        super();

        this._lastBoundObjectId = 1;
        this._idToWrappedObject = @createObjectWithoutPrototype();
        this._idToObjectGroupName = @createObjectWithoutPrototype();
        this._objectGroups = @createObjectWithoutPrototype();
        this._modules = @createObjectWithoutPrototype();
        this._nextSavedResultIndex = 1;
        this._savedResults = @createArrayWithoutPrototype();
    }

    //

    execute(functionString, objectGroup, includeCommandLineAPI, returnByValue, generatePreview, saveResult, args)
    {
        return this._wrapAndSaveCall(objectGroup, returnByValue, generatePreview, saveResult, () => {
            const isEvalOnCallFrame = false;
            return this._evaluateOn(InjectedScriptHost.evaluateWithScopeExtension, InjectedScriptHost, functionString, isEvalOnCallFrame, includeCommandLineAPI).@apply(@undefined, args);
        });
    }

    evaluate(expression, objectGroup, includeCommandLineAPI, returnByValue, generatePreview, saveResult)
    {
        const isEvalOnCallFrame = false;
        return this._evaluateAndWrap(InjectedScriptHost.evaluateWithScopeExtension, InjectedScriptHost, expression, objectGroup, isEvalOnCallFrame, includeCommandLineAPI, returnByValue, generatePreview, saveResult);
    }

    awaitPromise(promiseObjectId, returnByValue, generatePreview, saveResult, callback)
    {
        let parsedPromiseObjectId = this._parseObjectId(promiseObjectId);
        let promiseObject = this._objectForId(parsedPromiseObjectId);
        let promiseObjectGroupName = this._idToObjectGroupName[parsedPromiseObjectId.id];

        if (!isDefined(promiseObject)) {
            callback("Could not find object with given id");
            return;
        }

        if (!@isPromise(promiseObject)) {
            callback("Object with given id is not a Promise");
            return;
        }

        let resolve = (value) => {
            let returnObject = @createObjectWithoutPrototype(
                "wasThrown", false,
                "result", RemoteObject.create(value, promiseObjectGroupName, returnByValue, generatePreview),
            );

            if (saveResult) {
                this._savedResultIndex = 0;
                this._saveResult(returnObject.result);
                if (this._savedResultIndex)
                    returnObject.savedResultIndex = this._savedResultIndex;
            }

            callback(returnObject);
        };
        let reject = (reason) => {
            callback(this._createThrownValue(reason, promiseObjectGroupName));
        };
        promiseObject.@then(resolve, reject);
    }

    evaluateOnCallFrame(topCallFrame, callFrameId, expression, objectGroup, includeCommandLineAPI, returnByValue, generatePreview, saveResult)
    {
        let callFrame = this._callFrameForId(topCallFrame, callFrameId);
        if (!callFrame)
            return "Could not find call frame with given id";
        const isEvalOnCallFrame = true;
        return this._evaluateAndWrap(callFrame.evaluateWithScopeExtension, callFrame, expression, objectGroup, isEvalOnCallFrame, includeCommandLineAPI, returnByValue, generatePreview, saveResult);
    }

    callFunctionOn(objectId, expression, args, returnByValue, generatePreview, awaitPromise, callback)
    {
        let parsedObjectId = this._parseObjectId(objectId);
        let object = this._objectForId(parsedObjectId);
        let objectGroupName = this._idToObjectGroupName[parsedObjectId.id];

        if (!isDefined(object)) {
            callback("Could not find object with given id");
            return;
        }

        let resolvedArgs = @createArrayWithoutPrototype();
        if (args) {
            let callArgs = InjectedScriptHost.evaluate(args);
            for (let i = 0; i < callArgs.length; ++i) {
                try {
                    resolvedArgs[i] = this._resolveCallArgument(callArgs[i]);
                } catch (e) {
                    callback(@String(e));
                    return;
                }
            }
        }

        try {
            let func = InjectedScriptHost.evaluate("(" + expression + ")");
            if (typeof func !== "function") {
                callback("Given expression does not evaluate to a function");
                return;
            }
            let result = func.@apply(object, resolvedArgs);
            if (awaitPromise && isDefined(result) && @isPromise(result)) {
                result.then((value) => {
                    callback(@createObjectWithoutPrototype(
                        "wasThrown", false,
                        "result", RemoteObject.create(value, objectGroupName, returnByValue, generatePreview),
                    ));
                }, (reason) => {
                    callback(this._createThrownValue(reason, objectGroupName));
                });
            } else {
                callback(@createObjectWithoutPrototype(
                    "wasThrown", false,
                    "result", RemoteObject.create(result, objectGroupName, returnByValue, generatePreview),
                ));
            }
        } catch (e) {
            callback(this._createThrownValue(e, objectGroupName));
            return;
        }
    }

    getFunctionDetails(objectId)
    {
        let parsedObjectId = this._parseObjectId(objectId);
        let object = this._objectForId(parsedObjectId);
        if (typeof object !== "function")
            return "Cannot resolve function by id.";
        return this.functionDetails(object);
    }

    functionDetails(func)
    {
        let details = InjectedScriptHost.functionDetails(func);
        if (!details)
            return "Cannot resolve function details.";
        return details;
    }

    getPreview(objectId)
    {
        let parsedObjectId = this._parseObjectId(objectId);
        let object = this._objectForId(parsedObjectId);
        return RemoteObject.createObjectPreviewForValue(object, true);
    }

    getProperties(objectId, ownProperties, fetchStart, fetchCount, generatePreview)
    {
        let collectionMode = ownProperties ? InjectedScript.CollectionMode.OwnProperties : InjectedScript.CollectionMode.AllProperties;
        return this._getProperties(objectId, collectionMode, @createObjectWithoutPrototype(
            "fetchStart", fetchStart,
            "fetchCount", fetchCount,
            "generatePreview", generatePreview,
        ));
    }

    getDisplayableProperties(objectId, fetchStart, fetchCount, generatePreview)
    {
        let collectionMode = InjectedScript.CollectionMode.OwnProperties | InjectedScript.CollectionMode.NativeGetterProperties;
        return this._getProperties(objectId, collectionMode, @createObjectWithoutPrototype(
            "fetchStart", fetchStart,
            "fetchCount", fetchCount,
            "generatePreview", generatePreview,
            "nativeGettersAsValues", true,
        ));
    }

    getInternalProperties(objectId, generatePreview)
    {
        let parsedObjectId = this._parseObjectId(objectId);
        let object = this._objectForId(parsedObjectId);
        let objectGroupName = this._idToObjectGroupName[parsedObjectId.id];

        if (!isDefined(object))
            return false;

        if (isSymbol(object))
            return false;

        let descriptors = this._internalPropertyDescriptors(object);
        if (!descriptors)
            return @createArrayWithoutPrototype();

        for (let i = 0; i < descriptors.length; ++i) {
            let descriptor = descriptors[i];
            if ("value" in descriptor)
                descriptor.value = RemoteObject.create(descriptor.value, objectGroupName, false, generatePreview);
        }

        return descriptors;
    }

    getCollectionEntries(objectId, objectGroupName, fetchStart, fetchCount)
    {
        let parsedObjectId = this._parseObjectId(objectId);
        let object = this._objectForId(parsedObjectId);
        objectGroupName = objectGroupName || this._idToObjectGroupName[parsedObjectId.id];

        if (!isDefined(object))
            return;

        if (typeof object !== "object")
            return;

        let entries = this._entries(object, InjectedScriptHost.subtype(object), fetchStart, fetchCount);
        for (let i = 0; i < entries.length; ++i) {
            let entry = entries[i];
            entry.value = RemoteObject.create(entry.value, objectGroupName, false, true);
            if ("key" in entry)
                entry.key = RemoteObject.create(entry.key, objectGroupName, false, true);
        }
        return entries;
    }

    saveResult(callArgumentJSON)
    {
        this._savedResultIndex = 0;

        try {
            let callArgument = InjectedScriptHost.evaluate("(" + callArgumentJSON + ")");
            let value = this._resolveCallArgument(callArgument);
            this._saveResult(value);
        } catch { }

        return this._savedResultIndex;
    }

    wrapCallFrames(callFrame)
    {
        if (!callFrame)
            return false;

        let result = @createArrayWithoutPrototype();
        let depth = 0;
        do {
            @arrayPush(result, new InjectedScript.CallFrameProxy(depth++, callFrame));
            callFrame = callFrame.caller;
        } while (callFrame);
        return result;
    }

    wrapObject(object, groupName, canAccessInspectedGlobalObject, generatePreview)
    {
        if (!canAccessInspectedGlobalObject)
            return this._fallbackWrapper(object);

        return RemoteObject.create(object, groupName, false, generatePreview);
    }

    wrapJSONString(jsonString, groupName, generatePreview)
    {
        try {
            return this.wrapObject(@jsonParse(jsonString), groupName, true, generatePreview);
        } catch {
            return null;
        }
    }

    wrapTable(canAccessInspectedGlobalObject, table, columns)
    {
        if (!canAccessInspectedGlobalObject)
            return this._fallbackWrapper(table);

        //
        //
        //

        let columnNames = null;
        if (typeof columns === "string")
            columns = @createArrayWithoutPrototype(columns);

        if (InjectedScriptHost.subtype(columns) === "array") {
            columnNames = @createArrayWithoutPrototype();
            for (let i = 0; i < columns.length; ++i)
                @arrayPush(columnNames, toString(columns[i]));
        }

        return RemoteObject.create(table, "console", false, true, columnNames);
    }

    previewValue(value)
    {
        return RemoteObject.createObjectPreviewForValue(value, true);
    }

    setEventValue(value)
    {
        this._eventValue = value;
    }

    clearEventValue()
    {
        delete this._eventValue;
    }

    setExceptionValue(value)
    {
        this._exceptionValue = value;
    }

    clearExceptionValue()
    {
        delete this._exceptionValue;
    }

    findObjectById(objectId)
    {
        let parsedObjectId = this._parseObjectId(objectId);
        return this._objectForId(parsedObjectId);
    }

    releaseObject(objectId)
    {
        let parsedObjectId = this._parseObjectId(objectId);
        this._releaseObject(parsedObjectId.id);
    }

    releaseObjectGroup(objectGroupName)
    {
        if (objectGroupName === "console") {
            delete this._lastResult;
            this._nextSavedResultIndex = 1;
            this._savedResults = @createArrayWithoutPrototype();
        }

        let group = this._objectGroups[objectGroupName];
        if (!group)
            return;

        for (let i = 0; i < group.length; i++)
            this._releaseObject(group[i]);

        delete this._objectGroups[objectGroupName];
    }

    createCommandLineAPIObject(callFrame)
    {
        return new CommandLineAPI(callFrame || null);
    }

    //

    inspectObject(object)
    {
        if (this._inspectObject)
            this._inspectObject(object);
    }

    //

    hasInjectedModule(name)
    {
        return this._modules[name];
    }

    injectModule(name, moduleFunction, host)
    {
        this._modules[name] = false;

        if (typeof moduleFunction !== "function")
            throw "Error: Web Inspector: a function was expected for injectModule";
        moduleFunction(InjectedScriptHost, inspectedGlobalObject, injectedScriptId, this, @createObjectWithoutPrototype(
            "RemoteObject", RemoteObject,
            "CommandLineAPI", CommandLineAPI,
        ), host);

        this._modules[name] = true;
    }

    //

    isPrimitiveValue(value)
    {
        return isPrimitiveValue(value);
    }

    //

    _parseObjectId(objectId)
    {
        return InjectedScriptHost.evaluate("(" + objectId + ")");
    }

    _objectForId(objectId)
    {
        return this._idToWrappedObject[objectId.id];
    }

    _bind(object, objectGroupName)
    {
        let id = this._lastBoundObjectId++;
        let objectId = `{"injectedScriptId":${injectedScriptId},"id":${id}}`;

        this._idToWrappedObject[id] = object;

        if (objectGroupName) {
            let group = this._objectGroups[objectGroupName];
            if (!group) {
                group = @createArrayWithoutPrototype();
                this._objectGroups[objectGroupName] = group;
            }
            @arrayPush(group, id);
            this._idToObjectGroupName[id] = objectGroupName;
        }

        return objectId;
    }

    _releaseObject(id)
    {
        delete this._idToWrappedObject[id];
        delete this._idToObjectGroupName[id];
    }

    _fallbackWrapper(object)
    {
        let result = @createObjectWithoutPrototype("type", typeof object);
        if (isPrimitiveValue(object))
            result.value = object;
        else
            result.description = toStringDescription(object);
        return result;
    }

    _resolveCallArgument(callArgumentJSON)
    {
        if ("value" in callArgumentJSON)
            return callArgumentJSON.value;

        let objectId = callArgumentJSON.objectId;
        if (objectId) {
            let parsedArgId = this._parseObjectId(objectId);
            if (!parsedArgId || parsedArgId["injectedScriptId"] !== injectedScriptId)
                throw "Arguments should belong to the same JavaScript world as the target object.";

            let resolvedArg = this._objectForId(parsedArgId);
            if (!isDefined(resolvedArg))
                throw "Could not find object with given id";

            return resolvedArg;
        }

        return @undefined;
    }

    _createThrownValue(value, objectGroup)
    {
        let remoteObject = RemoteObject.create(value, objectGroup);
        try {
            remoteObject.description = toStringDescription(value);
        } catch { }
        return @createObjectWithoutPrototype(
            "wasThrown", true,
            "result", remoteObject,
        );
    }

    _evaluateAndWrap(evalFunction, object, expression, objectGroup, isEvalOnCallFrame, includeCommandLineAPI, returnByValue, generatePreview, saveResult)
    {
        return this._wrapAndSaveCall(objectGroup, returnByValue, generatePreview, saveResult, () => {
            return this._evaluateOn(evalFunction, object, expression, isEvalOnCallFrame, includeCommandLineAPI);
        });
    }

    _wrapAndSaveCall(objectGroup, returnByValue, generatePreview, saveResult, func)
    {
        return this._wrapCall(objectGroup, returnByValue, generatePreview, saveResult, () => {
            let result = func();
            if (saveResult)
                this._saveResult(result);
            return result;
        });
    }

    _wrapCall(objectGroup, returnByValue, generatePreview, saveResult, func)
    {
        try {
            this._savedResultIndex = 0;

            let returnObject = @createObjectWithoutPrototype(
                "wasThrown", false,
                "result", RemoteObject.create(func(), objectGroup, returnByValue, generatePreview),
            );

            if (saveResult && this._savedResultIndex)
                returnObject.savedResultIndex = this._savedResultIndex;

            return returnObject;
        } catch (e) {
            return this._createThrownValue(e, objectGroup);
        }
    }

    _evaluateOn(evalFunction, object, expression, isEvalOnCallFrame, includeCommandLineAPI)
    {
        let commandLineAPI = null;
        if (includeCommandLineAPI)
            commandLineAPI = this.createCommandLineAPIObject(isEvalOnCallFrame ? object : null);
        return evalFunction.@call(object, expression, commandLineAPI);
    }

    _callFrameForId(topCallFrame, callFrameId)
    {
        let parsedCallFrameId = InjectedScriptHost.evaluate("(" + callFrameId + ")");
        let ordinal = parsedCallFrameId["ordinal"];
        let callFrame = topCallFrame;
        while (--ordinal >= 0 && callFrame)
            callFrame = callFrame.caller;
        return callFrame;
    }

    _getProperties(objectId, collectionMode, {fetchStart, fetchCount, generatePreview, nativeGettersAsValues})
    {
        let parsedObjectId = this._parseObjectId(objectId);
        let object = this._objectForId(parsedObjectId);
        let objectGroupName = this._idToObjectGroupName[parsedObjectId.id];

        if (!isDefined(object))
            return false;

        if (isSymbol(object))
            return false;

        let start = fetchStart || 0;
        if (start < 0)
            start = 0;

        let count = fetchCount || 0;
        if (count < 0)
            count = 0;

        //
        let includeProto = !start;

        let descriptors = @createArrayWithoutPrototype();
        this._forEachPropertyDescriptor(object, collectionMode, (descriptor) => {
            if (start > 0) {
                --start;
                return InjectedScript.PropertyFetchAction.Continue;
            }

            if ("get" in descriptor)
                descriptor.get = RemoteObject.create(descriptor.get, objectGroupName);
            if ("set" in descriptor)
                descriptor.set = RemoteObject.create(descriptor.set, objectGroupName);
            if ("value" in descriptor)
                descriptor.value = RemoteObject.create(descriptor.value, objectGroupName, false, generatePreview);
            if ("symbol" in descriptor)
                descriptor.symbol = RemoteObject.create(descriptor.symbol, objectGroupName);
            @arrayPush(descriptors, descriptor);

            if (includeProto && count && descriptors.length >= count && descriptor.name !== "__proto__")
                return InjectedScript.PropertyFetchAction.Stop;

            return (count && descriptors.length >= count) ? InjectedScript.PropertyFetchAction.Stop : InjectedScript.PropertyFetchAction.Continue;
        }, @createObjectWithoutPrototype(
            "nativeGettersAsValues", nativeGettersAsValues,
            "includeProto", includeProto,
        ));
        return descriptors;
    }

    _internalPropertyDescriptors(object, completeDescriptor)
    {
        let internalProperties = InjectedScriptHost.getInternalProperties(object);
        if (!internalProperties)
            return null;

        let descriptors = @createArrayWithoutPrototype();
        for (let i = 0; i < internalProperties.length; i++) {
            let property = internalProperties[i];
            let descriptor = @createObjectWithoutPrototype(
                "name", property.name,
                "value", property.value,
            );
            if (completeDescriptor)
                descriptor.isOwn = true;
            @arrayPush(descriptors, descriptor);
        }
        return descriptors;
    }

    _forEachPropertyDescriptor(object, collectionMode, callback, {nativeGettersAsValues, includeProto})
    {
        let subtype = RemoteObject.subtype(object);
        if (subtype === "proxy" || subtype === "weakref")
            return;

        let nameProcessed = new @Set;

        //
        nameProcessed.@add("__proto__");

        function createFakeValueDescriptor(name, symbol, descriptor, isOwnProperty, possibleNativeBindingGetter)
        {
            try {
                let fakeDescriptor = @createObjectWithoutPrototype(
                    "name", name,
                    "value", object[name],
                );
                if (descriptor) {
                    if (descriptor.writable)
                        fakeDescriptor.writable = true;
                    if (descriptor.configurable)
                        fakeDescriptor.configurable = true;
                    if (descriptor.enumerable)
                        fakeDescriptor.enumerable = true;
                }
                if (possibleNativeBindingGetter)
                    fakeDescriptor.nativeGetter = true;
                if (isOwnProperty)
                    fakeDescriptor.isOwn = true;
                if (symbol)
                    fakeDescriptor.symbol = symbol;
                //
                if (@isPromise(fakeDescriptor.value) && InjectedScriptHost.isPromiseRejectedWithNativeGetterTypeError(fakeDescriptor.value))
                    fakeDescriptor.value.@catch(function(){});
                return fakeDescriptor;
            } catch (e) {
                let errorDescriptor = @createObjectWithoutPrototype(
                    "name", name,
                    "value", e,
                    "wasThrown", true,
                );
                if (isOwnProperty)
                    errorDescriptor.isOwn = true;
                if (symbol)
                    errorDescriptor.symbol = symbol;
                return errorDescriptor;
            }
        }

        function processDescriptor(descriptor, isOwnProperty, possibleNativeBindingGetter)
        {
            //
            if (collectionMode & InjectedScript.CollectionMode.AllProperties)
                return callback(descriptor);

            //
            if (collectionMode & InjectedScript.CollectionMode.OwnProperties && isOwnProperty)
                return callback(descriptor);

            //
            if (collectionMode & InjectedScript.CollectionMode.NativeGetterProperties) {
                if (possibleNativeBindingGetter)
                    return callback(descriptor);
            }
        }

        function processProperty(o, propertyName, isOwnProperty, isPrivate)
        {
            if (nameProcessed.@has(propertyName))
                return InjectedScript.PropertyFetchAction.Continue;

            nameProcessed.@add(propertyName);

            //
            let name = isPrivate ? propertyName.description : toString(propertyName);
            let symbol = (!isPrivate && isSymbol(propertyName)) ? propertyName : null;

            let descriptor = @Object.@getOwnPropertyDescriptor(o, propertyName);
            if (!descriptor) {
                //
                //
                let fakeDescriptor = createFakeValueDescriptor(name, symbol, descriptor, isOwnProperty);
                return processDescriptor(fakeDescriptor, isOwnProperty);
            }

            if (nativeGettersAsValues) {
                if (@String(descriptor.get).@endsWith("[native code]\n}") || (!descriptor.get && @Object.@hasOwn(descriptor, "get") && !descriptor.set && @Object.@hasOwn(descriptor, "set"))) {
                    //
                    //
                    let fakeDescriptor = createFakeValueDescriptor(name, symbol, descriptor, isOwnProperty, true);
                    return processDescriptor(fakeDescriptor, isOwnProperty, true);
                }
            }

            descriptor.name = name;
            if (isOwnProperty)
                descriptor.isOwn = true;
            if (symbol)
                descriptor.symbol = symbol;
            if (isPrivate)
                descriptor.isPrivate = true;
            return processDescriptor(descriptor, isOwnProperty);
        }

        let isArrayLike = false;
        try {
            isArrayLike = subtype === "array" && @isFinite(object.length) && object.length > 0;
        } catch { }

        for (let o = object; isDefined(o); o = @Object.@getPrototypeOf(o)) {
            let isOwnProperty = o === object;
            let shouldBreak = false;

            let privatePropertySymbols = InjectedScriptHost.getOwnPrivatePropertySymbols(o);
            for (let i = 0; i < privatePropertySymbols.length; ++i) {
                let privatePropertySymbol = privatePropertySymbols[i];
                let result = processProperty(o, privatePropertySymbol, isOwnProperty, true);
                shouldBreak = result === InjectedScript.PropertyFetchAction.Stop;
                if (shouldBreak)
                    break;
            }

            if (shouldBreak)
                break;

            //
            if (isArrayLike && isOwnProperty) {
                for (let i = 0; i < o.length; ++i) {
                    if (!(i in o))
                        continue;

                    let result = processProperty(o, toString(i), isOwnProperty);
                    shouldBreak = result === InjectedScript.PropertyFetchAction.Stop;
                    if (shouldBreak)
                        break;
                }
            } else {
                let propertyNames = @Object.@getOwnPropertyNames(o);
                for (let i = 0; i < propertyNames.length; ++i) {
                    let result = processProperty(o, propertyNames[i], isOwnProperty);
                    shouldBreak = result === InjectedScript.PropertyFetchAction.Stop;
                    if (shouldBreak)
                        break;
                }
            }

            if (shouldBreak)
                break;

            let propertySymbols = @Object.@getOwnPropertySymbols(o);
            for (let i = 0; i < propertySymbols.length; ++i) {
                let result = processProperty(o, propertySymbols[i], isOwnProperty);
                shouldBreak = result === InjectedScript.PropertyFetchAction.Stop;
                if (shouldBreak)
                    break;
            }

            if (shouldBreak)
                break;

            if (collectionMode === InjectedScript.CollectionMode.OwnProperties)
                break;
        }

        if (includeProto) {
            try {
                if (object.__proto__)
                    callback(@createObjectWithoutPrototype(
                        "name", "__proto__",
                        "value", object.__proto__,
                        "writable", true,
                        "configurable", true,
                        "isOwn", true,
                    ));
            } catch { }
        }
    }

    _getSetEntries(object, fetchStart, fetchCount)
    {
        let entries = @createArrayWithoutPrototype();

        for (let value of @builtinSetIterable(object)) {
            if (fetchStart > 0) {
                fetchStart--;
                continue;
            }

            @arrayPush(entries, @createObjectWithoutPrototype("value", value));

            if (fetchCount && entries.length === fetchCount)
                break;
        }

        return entries;
    }

    _getMapEntries(object, fetchStart, fetchCount)
    {
        let entries = @createArrayWithoutPrototype();

        for (let [key, value] of @builtinMapIterable(object)) {
            if (fetchStart > 0) {
                fetchStart--;
                continue;
            }

            @arrayPush(entries, @createObjectWithoutPrototype(
                "key", key,
                "value", value,
            ));

            if (fetchCount && entries.length === fetchCount)
                break;
        }

        return entries;
    }

    _getWeakMapEntries(object, fetchCount)
    {
        return InjectedScriptHost.weakMapEntries(object, fetchCount);
    }

    _getWeakSetEntries(object, fetchCount)
    {
        return InjectedScriptHost.weakSetEntries(object, fetchCount);
    }

    _getIteratorEntries(object, fetchCount)
    {
        return InjectedScriptHost.iteratorEntries(object, fetchCount);
    }

    _entries(object, subtype, fetchStart, fetchCount)
    {
        if (subtype === "set")
            return this._getSetEntries(object, fetchStart, fetchCount);
        if (subtype === "map")
            return this._getMapEntries(object, fetchStart, fetchCount);
        if (subtype === "weakmap")
            return this._getWeakMapEntries(object, fetchCount);
        if (subtype === "weakset")
            return this._getWeakSetEntries(object, fetchCount);
        if (subtype === "iterator")
            return this._getIteratorEntries(object, fetchCount);

        throw "unexpected type";
    }

    _saveResult(result)
    {
        this._lastResult = result;

        if (result === @undefined || result === null)
            return;

        let existingIndex = @Array.prototype.@indexOf.@call(this._savedResults, result);
        if (existingIndex !== -1) {
            this._savedResultIndex = existingIndex;
            return;
        }

        this._savedResultIndex = this._nextSavedResultIndex;
        this._savedResults[this._nextSavedResultIndex++] = result;

        //
        if (this._nextSavedResultIndex >= 100)
            this._nextSavedResultIndex = 1;
    }
};

InjectedScript.CollectionMode = @createObjectWithoutPrototype(
    "OwnProperties", 1 << 0,          //
    "NativeGetterProperties", 1 << 1, //
    "AllProperties", 1 << 2,          //
);

InjectedScript.PropertyFetchAction = @createObjectWithoutPrototype(
    "Continue", @createPrivateSymbol("continue"),
    "Stop", @createPrivateSymbol("stop"),
);

var injectedScript = new InjectedScript;

//

let RemoteObject = class RemoteObject extends PrototypelessObjectBase
{
    constructor(object, objectGroupName, forceValueType, generatePreview, columnNames)
    {
        super();

        this.type = typeof object;

        if (this.type === "undefined" && InjectedScriptHost.isHTMLAllCollection(object))
            this.type = "object";

        if (isPrimitiveValue(object) || isBigInt(object) || object === null || forceValueType) {
            //
            //
            if (this.type !== "undefined" && this.type !== "bigint")
                this.value = object;

            //
            if (object === null)
                this.subtype = "null";

            //
            if (this.type === "number" || this.type === "bigint")
                this.description = toStringDescription(object);

            return;
        }

        this.objectId = injectedScript._bind(object, objectGroupName);

        let subtype = RemoteObject.subtype(object);
        if (subtype)
            this.subtype = subtype;

        this.className = InjectedScriptHost.internalConstructorName(object);
        this.description = RemoteObject.describe(object);

        if (subtype === "array")
            this.size = typeof object.length === "number" ? object.length : 0;
        else if (subtype === "set" || subtype === "map")
            this.size = object.size;
        else if (subtype === "weakmap")
            this.size = InjectedScriptHost.weakMapSize(object);
        else if (subtype === "weakset")
            this.size = InjectedScriptHost.weakSetSize(object);
        else if (subtype === "class") {
            this.classPrototype = RemoteObject.create(object.prototype, objectGroupName);
            this.className = object.name;
        }

        if (generatePreview && this.type === "object") {
            if (subtype === "proxy") {
                this.preview = this._generatePreview(InjectedScriptHost.proxyTargetValue(object));
                this.preview.lossless = false;
            } else if (subtype === "weakref") {
                this.preview = this._generatePreview(InjectedScriptHost.weakRefTargetValue(object));
                this.preview.lossless = false;
            } else
                this.preview = this._generatePreview(object, @undefined, columnNames);
        }
    }

    //

    static create(object, objectGroupName, forceValueType, generatePreview, columnNames)
    {
        try {
            return new RemoteObject(object, objectGroupName, forceValueType, generatePreview, columnNames);
        } catch (e) {
            let description;
            try {
                description = RemoteObject.describe(e);
            } catch (ex) {
                inspectedGlobalObject.console.error(ex.message);
                description = "<failed to convert exception to string>";
            }
            return new RemoteObject(description);
        }
    }

    static createObjectPreviewForValue(value, generatePreview, columnNames)
    {
        let remoteObject = new RemoteObject(value, @undefined, false, generatePreview, columnNames);
        if (remoteObject.objectId)
            injectedScript.releaseObject(remoteObject.objectId);
        if (remoteObject.classPrototype && remoteObject.classPrototype.objectId)
            injectedScript.releaseObject(remoteObject.classPrototype.objectId);
        return remoteObject.preview || remoteObject._emptyPreview();
    }

    static subtype(value)
    {
        if (value === null)
            return "null";

        if (isPrimitiveValue(value) || isBigInt(value) || isSymbol(value))
            return null;

        if (InjectedScriptHost.isHTMLAllCollection(value))
            return "array";

        let preciseType = InjectedScriptHost.subtype(value);
        if (preciseType)
            return preciseType;

        //
        try {
            if (typeof value.splice === "function" && @isFinite(value.length))
                return "array";
        } catch { }

        return null;
    }

    static describe(value)
    {
        if (isPrimitiveValue(value))
            return null;

        if (isBigInt(value))
            return null;

        if (isSymbol(value))
            return toString(value);

        let subtype = RemoteObject.subtype(value);

        if (subtype === "regexp")
            return toString(value);

        if (subtype === "date")
            return toString(value);

        if (subtype === "error")
            return toString(value);

        if (subtype === "proxy")
            return "Proxy";

        if (subtype === "weakref")
            return "WeakRef";

        if (subtype === "node")
            return RemoteObject.nodePreview(value);

        let className = InjectedScriptHost.internalConstructorName(value);
        if (subtype === "array")
            return className;

        if (subtype === "iterator" && @@toStringTag in value)
            return value.@@toStringTag;

        //
        if (typeof value === "function")
            return value.toString();

        //
        if (className === "Object") {
            let constructorName = value.constructor && value.constructor.name;
            if (constructorName)
                return constructorName;
        }

        return className;
    }

    static nodePreview(node)
    {
        //
        let isXMLDocument = node.ownerDocument && !!node.ownerDocument.xmlVersion;
        let nodeName = isXMLDocument ? node.nodeName : node.nodeName.toLowerCase();

        switch (node.nodeType) {
        case 1: //
            if (node.id)
                return "<" + nodeName + " id=\"" + node.id + "\">";
            if (node.classList.length)
                return "<" + nodeName + " class=\"" + node.classList.toString().replace(/\s+/, " ") + "\">";
            if (nodeName === "input" && node.type)
                return "<" + nodeName + " type=\"" + node.type + "\">";
            return "<" + nodeName + ">";

        case 3: //
            return nodeName + " \"" + node.nodeValue + "\"";

        case 8: //
            return "<!--" + node.nodeValue + "-->";

        case 10: //
            return "<!DOCTYPE " + nodeName + ">";

        default:
            return nodeName;
        }
    }

    //

    _initialPreview()
    {
        let preview = @createObjectWithoutPrototype(
            "type", this.type,
            "description", this.description || toString(this.value),
            "lossless", true,
        );

        if (this.subtype) {
            preview.subtype = this.subtype;
            if (this.subtype !== "null") {
                preview.overflow = false;
                preview.properties = @createArrayWithoutPrototype();
            }
        }

        if ("size" in this)
            preview.size = this.size;

        return preview;
    }

    _emptyPreview()
    {
        let preview = this._initialPreview();

        if (this.subtype === "map" || this.subtype === "set" || this.subtype === "weakmap" || this.subtype === "weakset" || this.subtype === "iterator") {
            if (this.size) {
                preview.entries = @createArrayWithoutPrototype();
                preview.lossless = false;
                preview.overflow = true;
            }
        }

        return preview;
    }

    _generatePreview(object, firstLevelKeys, secondLevelKeys)
    {
        let preview = this._initialPreview();
        let isTableRowsRequest = secondLevelKeys === null || secondLevelKeys;
        let firstLevelKeysCount = firstLevelKeys ? firstLevelKeys.length : 0;

        let propertiesThreshold = @createObjectWithoutPrototype(
            "properties", isTableRowsRequest ? 1000 : max(5, firstLevelKeysCount),
            "indexes", isTableRowsRequest ? 1000 : max(10, firstLevelKeysCount),
        );

        try {
            //
            if (this.subtype === "map" || this.subtype === "set" || this.subtype === "weakmap" || this.subtype === "weakset" || this.subtype === "iterator")
                this._appendEntryPreviews(object, preview);

            preview.properties = @createArrayWithoutPrototype();

            //
            let internalPropertyDescriptors = injectedScript._internalPropertyDescriptors(object, true);
            if (internalPropertyDescriptors) {
                for (let i = 0; i < internalPropertyDescriptors.length; ++i) {
                    let result = this._appendPropertyPreview(object, preview, internalPropertyDescriptors[i], propertiesThreshold, firstLevelKeys, secondLevelKeys, @createObjectWithoutPrototype("internal", true));
                    if (result === InjectedScript.PropertyFetchAction.Stop)
                        return preview;
                }
            }

            if (preview.entries)
                return preview;

            //
            injectedScript._forEachPropertyDescriptor(object, InjectedScript.CollectionMode.AllProperties, (descriptor) => {
                return this._appendPropertyPreview(object, preview, descriptor, propertiesThreshold, firstLevelKeys, secondLevelKeys);
            }, @createObjectWithoutPrototype(
                "nativeGettersAsValues", true,
                "includeProto", true,
            ));
        } catch {
            preview.lossless = false;
        }

        return preview;
    }

    _appendPropertyPreview(object, preview, descriptor, propertiesThreshold, firstLevelKeys, secondLevelKeys, {internal} = @createObjectWithoutPrototype())
    {
        //
        if (descriptor.wasThrown) {
            preview.lossless = false;
            return InjectedScript.PropertyFetchAction.Continue;
        }

        //
        let name = descriptor.name;
        if (name === "__proto__") {
            //
            if (descriptor.value && descriptor.value.constructor
                && descriptor.value.constructor !== @Object
                && descriptor.value.constructor !== @Array
                && descriptor.value.constructor !== @RegExp)
                preview.lossless = false;
            return InjectedScript.PropertyFetchAction.Continue;
        }

        //
        if (this.subtype === "array" && !isUInt32(name))
            return InjectedScript.PropertyFetchAction.Continue;

        //
        //
        //
        if (!descriptor.enumerable && !descriptor.isOwn && !(this.subtype === "array" || (this.subtype !== "regexp" && descriptor.nativeGetter)))
            return InjectedScript.PropertyFetchAction.Continue;

        //
        //
        if (firstLevelKeys && !@Array.prototype.@includes.@call(firstLevelKeys, name))
            return InjectedScript.PropertyFetchAction.Continue;

        function appendPreview(property) {
            if (toString(property.name >>> 0) === property.name)
                propertiesThreshold.indexes--;
            else
                propertiesThreshold.properties--;

            if (propertiesThreshold.indexes < 0 || propertiesThreshold.properties < 0) {
                preview.overflow = true;
                preview.lossless = false;
                return InjectedScript.PropertyFetchAction.Stop;
            }

            if (descriptor.isPrivate)
                property.isPrivate = true;

            if (internal)
                property.internal = true;

            @arrayPush(preview.properties, property);
            return InjectedScript.PropertyFetchAction.Continue;
        }

        //
        if (!("value" in descriptor)) {
            preview.lossless = false;
            return appendPreview(@createObjectWithoutPrototype(
                "name", name,
                "type", "accessor",
            ));
        }

        //
        let value = descriptor.value;
        if (value === null)
            return appendPreview(@createObjectWithoutPrototype(
                "name", name,
                "type", "object",
                "subtype", "null",
                "value", "null",
            ));

        //
        let type = typeof value;
        if (!descriptor.enumerable && type === "function")
            return InjectedScript.PropertyFetchAction.Continue;

        //
        if (InjectedScriptHost.isHTMLAllCollection(value))
            type = "object";

        //
        const maxLength = 100;
        if (isPrimitiveValue(value) || isBigInt(value)) {
            if (type === "string" && value.length > maxLength) {
                value = this._abbreviateString(value, maxLength, true);
                preview.lossless = false;
            }
            return appendPreview(@createObjectWithoutPrototype(
                "name", name,
                "type", type,
                "value", toStringDescription(value),
            ));
        }

        //
        if (isSymbol(value)) {
            let symbolString = toString(value);
            if (symbolString.length > maxLength) {
                symbolString = this._abbreviateString(symbolString, maxLength, true);
                preview.lossless = false;
            }
            return appendPreview(@createObjectWithoutPrototype(
                "name", name,
                "type", type,
                "value", symbolString,
            ));
        }

        //
        let property = @createObjectWithoutPrototype(
            "name", name,
            "type", type,
        );
        let subtype = RemoteObject.subtype(value);
        if (subtype)
            property.subtype = subtype;

        //
        if ((secondLevelKeys === null || secondLevelKeys) || this._isPreviewableObject(value, object)) {
            //
            let subPreview = RemoteObject.createObjectPreviewForValue(value, value !== object, secondLevelKeys);
            property.valuePreview = subPreview;
            if (!subPreview.lossless)
                preview.lossless = false;
            if (subPreview.overflow)
                preview.overflow = true;
        } else {
            let description = "";
            if (type !== "function" || subtype === "class") {
                let fullDescription;
                if (subtype === "class")
                    fullDescription = "class " + value.name;
                else if (subtype === "node")
                    fullDescription = RemoteObject.nodePreview(value);
                else
                    fullDescription = RemoteObject.describe(value);
                description = this._abbreviateString(fullDescription, maxLength, subtype === "regexp");
            }
            property.value = description;
            preview.lossless = false;
        }

        return appendPreview(property);
    }

    _appendEntryPreviews(object, preview)
    {
        //
        let entries = injectedScript._entries(object, this.subtype, 0, 6);
        if (!entries)
            return;

        if (entries.length > 5) {
            @Array.prototype.@pop.@call(entries);
            preview.overflow = true;
            preview.lossless = false;
        }

        function updateMainPreview(subPreview) {
            if (!subPreview.lossless)
                preview.lossless = false;
        }

        preview.entries = @Array.prototype.@map.@call(entries, function(entry) {
            entry.value = RemoteObject.createObjectPreviewForValue(entry.value, entry.value !== object);
            updateMainPreview(entry.value);
            if ("key" in entry) {
                entry.key = RemoteObject.createObjectPreviewForValue(entry.key, entry.key !== object);
                updateMainPreview(entry.key);
            }
            return entry;
        });
    }

    _isPreviewableObject(value, object)
    {
        let set = new @Set;
        set.@add(object);

        return this._isPreviewableObjectInternal(value, set, 1);
    }

    _isPreviewableObjectInternal(object, knownObjects, depth)
    {
        //
        if (depth > 3)
            return false;

        //
        if (isPrimitiveValue(object) || isBigInt(object) || isSymbol(object))
            return true;

        //
        if (object === null)
            return true;

        //
        if (knownObjects.@has(object))
            return false;

        ++depth;
        knownObjects.@add(object);

        //
        let subtype = RemoteObject.subtype(object);
        if (subtype === "array") {
            let length = object.length;
            if (length > 5)
                return false;
            for (let i = 0; i < length; ++i) {
                if (!this._isPreviewableObjectInternal(object[i], knownObjects, depth))
                    return false;
            }
            return true;
        }

        //
        if (object.__proto__ && object.__proto__.__proto__)
            return false;

        //
        let ownPropertyNames = @Object.@getOwnPropertyNames(object);
        if (ownPropertyNames.length > 3)
            return false;
        for (let i = 0; i < ownPropertyNames.length; ++i) {
            let propertyName = ownPropertyNames[i];
            let descriptor = @Object.@getOwnPropertyDescriptor(object, propertyName);
            if (descriptor && !("value" in descriptor))
                return false;
            if (!this._isPreviewableObjectInternal(object[propertyName], knownObjects, depth))
                return false;
        }

        return true;
    }

    _abbreviateString(string, maxLength, middle)
    {
        if (string.length <= maxLength)
            return string;

        if (middle) {
            let leftHalf = maxLength >> 1;
            let rightHalf = maxLength - leftHalf - 1;
            return string.@substr(0, leftHalf) + "\u2026" + string.@substr(string.length - rightHalf, rightHalf);
        }

        return string.@substr(0, maxLength) + "\u2026";
    }
};

//

InjectedScript.CallFrameProxy = class CallFrameProxy extends PrototypelessObjectBase
{
    constructor(ordinal, callFrame)
    {
        super();

        this.callFrameId = `{"ordinal":${ordinal},"injectedScriptId":${injectedScriptId}}`;
        this.functionName = callFrame.functionName;

        this.location = @createObjectWithoutPrototype(
            "scriptId", @String(callFrame.sourceID),
            "lineNumber", callFrame.line,
            "columnNumber", callFrame.column,
        );

        this.scopeChain = this._wrapScopeChain(callFrame);
        this.this = RemoteObject.create(callFrame.thisObject, "backtrace");
        this.isTailDeleted = callFrame.isTailDeleted;
    }

    _wrapScopeChain(callFrame)
    {
        let scopeChain = callFrame.scopeChain;
        let scopeDescriptions = callFrame.scopeDescriptions();

        let scopeChainProxy = @createArrayWithoutPrototype();
        for (let i = 0; i < scopeChain.length; i++)
            scopeChainProxy[i] = InjectedScript.CallFrameProxy._createScopeJson(scopeChain[i], scopeDescriptions[i], "backtrace");
        return scopeChainProxy;
    }

    static _createScopeJson(object, {name, type, location}, groupId)
    {
        let scope = @createObjectWithoutPrototype(
            "object", RemoteObject.create(object, groupId),
            "type", InjectedScript.CallFrameProxy._scopeTypeNames[type],
        );

        if (name)
            scope.name = name;

        if (location)
            scope.location = location;

        if (isEmptyObject(object))
            scope.empty = true;

        return scope;
    }
};

InjectedScript.CallFrameProxy._scopeTypeNames = @createObjectWithoutPrototype(
    0, "global", //
    1, "with", //
    2, "closure", //
    3, "catch", //
    4, "functionName", //
    5, "globalLexicalEnvironment", //
    6, "nestedLexical", //
);

//

function CommandLineAPI(callFrame)
{
    let savedResultAlias = InjectedScriptHost.savedResultAlias;

    let defineGetter = (key, value, wrap) => {
        if (wrap) {
            let originalValue = value;
            value = function() { return originalValue; };
        }

        @Object.@defineProperty(this, "$" + key, @createObjectWithoutPrototype("get", value));
        if (savedResultAlias && savedResultAlias !== "$")
            @Object.@defineProperty(this, savedResultAlias + key, @createObjectWithoutPrototype("get", value));
    };

    if ("_lastResult" in injectedScript)
        defineGetter("_", injectedScript._lastResult, true);

    if ("_exceptionValue" in injectedScript)
        defineGetter("exception", injectedScript._exceptionValue, true);

    if ("_eventValue" in injectedScript)
        defineGetter("event", injectedScript._eventValue, true);

    //
    for (let i = 1; i < injectedScript._savedResults.length; ++i)
        defineGetter(i, injectedScript._savedResults[i], true);

    for (let name in CommandLineAPI.getters)
        defineGetter(name, CommandLineAPI.getters[name]);

    for (let name in CommandLineAPI.methods)
        this[name] = CommandLineAPI.methods[name];
}

CommandLineAPI.getters = @createObjectWithoutPrototype();

CommandLineAPI.methods = @createObjectWithoutPrototype();

CommandLineAPI.methods["keys"] = function(object) { return @Object.@keys(object); };
CommandLineAPI.methods["values"] = function(object) { return @Object.@values(object); };

CommandLineAPI.methods["queryInstances"] = function() { return InjectedScriptHost.queryInstances(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["queryObjects"] = function() { return InjectedScriptHost.queryInstances(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["queryHolders"] = function() { return InjectedScriptHost.queryHolders(...createIterableWithoutPrototypeFromArguments(arguments)); };

CommandLineAPI.methods["inspect"] = function(object) { return injectedScript.inspectObject(object); };

CommandLineAPI.methods["assert"] = function() { return inspectedGlobalObject.console.assert(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["clear"] = function() { return inspectedGlobalObject.console.clear(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["count"] = function() { return inspectedGlobalObject.console.count(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["countReset"] = function() { return inspectedGlobalObject.console.countReset(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["debug"] = function() { return inspectedGlobalObject.console.debug(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["dir"] = function() { return inspectedGlobalObject.console.dir(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["dirxml"] = function() { return inspectedGlobalObject.console.dirxml(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["error"] = function() { return inspectedGlobalObject.console.error(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["group"] = function() { return inspectedGlobalObject.console.group(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["groupCollapsed"] = function() { return inspectedGlobalObject.console.groupCollapsed(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["groupEnd"] = function() { return inspectedGlobalObject.console.groupEnd(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["info"] = function() { return inspectedGlobalObject.console.info(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["log"] = function() { return inspectedGlobalObject.console.log(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["profile"] = function() { return inspectedGlobalObject.console.profile(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["profileEnd"] = function() { return inspectedGlobalObject.console.profileEnd(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["record"] = function() { return inspectedGlobalObject.console.record(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["recordEnd"] = function() { return inspectedGlobalObject.console.recordEnd(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["screenshot"] = function() { return inspectedGlobalObject.console.screenshot(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["table"] = function() { return inspectedGlobalObject.console.table(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["takeHeapSnapshot"] = function() { return inspectedGlobalObject.console.takeHeapSnapshot(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["time"] = function() { return inspectedGlobalObject.console.time(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["timeEnd"] = function() { return inspectedGlobalObject.console.timeEnd(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["timeLog"] = function() { return inspectedGlobalObject.console.timeLog(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["timeStamp"] = function() { return inspectedGlobalObject.console.timeStamp(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["trace"] = function() { return inspectedGlobalObject.console.trace(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["warn"] = function() { return inspectedGlobalObject.console.warn(...createIterableWithoutPrototypeFromArguments(arguments)); };

for (let name in CommandLineAPI.methods)
    CommandLineAPI.methods[name].toString = function() { return "function " + name + "() { [Command Line API] }"; };

return injectedScript;
})
(function ()
{
    if (arguments.length % 2 !== 0)
        @throwRangeError("`createObjectWithoutPrototype` requires that each key argument be followed by a value, resulting in an even number of arguments.");

    let object = @Object.@create(null)
    for (let i = 0; i < arguments.length; i += 2)
        object[arguments[i]] = arguments[i + 1];

    return object;
})
(function (promise)
{
    "use strict";
    @assert(@isPromise(promise));

    var alreadyResolved = false;

    var resolve = (0,  (resolution) => {
        if (alreadyResolved)
            return @undefined;
        alreadyResolved = true;

        return @resolvePromise(promise, resolution);
    });

    var reject = (0,  (reason) => {
        if (alreadyResolved)
            return @undefined;
        alreadyResolved = true;

        return @rejectPromise(promise, reason);
    });

    return { resolve, reject };
})
(function (onFulfilled, onRejected, context)
{
    "use strict";

    var alreadyResolved = false;

    var resolve = (0,  (resolution) => {
        if (alreadyResolved)
            return @undefined;
        alreadyResolved = true;

        @resolveWithoutPromise(resolution, onFulfilled, onRejected, context);
    });

    var reject = (0,  (reason) => {
        if (alreadyResolved)
            return @undefined;
        alreadyResolved = true;

        @rejectWithoutPromise(reason, onFulfilled, onRejected, context);
    });

    return { resolve, reject };
})
(function (error)
{
    "use strict";

    //
    @throwTypeError(@toString(error));
})
(async function (asyncItems, mapFn, thisArg)
{
    "use strict";

    var arrayLike = @toObject(asyncItems, "Array.fromAsync requires an array-like object - not null or undefined");

    var arrayLikeLength = @toLength(arrayLike.length);

    var result = this !== @Array && @isConstructor(this) ? new this(arrayLikeLength) : @newArrayWithSize(arrayLikeLength);

    var k = 0;
    while (k < arrayLikeLength) {
        var value = await arrayLike[k];
        if (mapFn === @undefined)
            @putByValDirect(result, k, value);
        else
            @putByValDirect(result, k, await (thisArg === @undefined ? mapFn(value, k) : mapFn.@call(thisArg, value, k)));
        k += 1;
    }

    result.length = arrayLikeLength;
    return result;
})
(async function (iterator, mapFn, thisArg)
{
    "use strict";

    var result = this !== @Array && @isConstructor(this) ? new this() : [];

    var k = 0;

    //
    //
    //
    var wrapper = {
        @@asyncIterator: function () { return iterator; }
    };

    for await (var value of wrapper) {
        if (k >= @MAX_SAFE_INTEGER)
            @throwTypeError("Length exceeded the maximum array length");
        if (mapFn === @undefined)
            @putByValDirect(result, k, value);
        else
            @putByValDirect(result, k, await (thisArg === @undefined ? mapFn(value, k) : mapFn.@call(thisArg, value, k)));
        k += 1;
    }

    result.length = k;
    return result;
})
(function (onAsyncDispose)
{
    'use strict';

    if (!@isAsyncDisposableStack(this))
        @throwTypeError("AsyncDisposableStack.prototype.defer requires that |this| be a AsyncDisposableStack object");

    if (@getAsyncDisposableStackInternalField(this, @asyncDisposableStackFieldState) === @AsyncDisposableStackStateDisposed)
        throw new @ReferenceError("AsyncDisposableStack.prototype.defer requires that |this| be a pending AsyncDisposableStack object");

    if (!@isCallable(onAsyncDispose))
        @throwTypeError("AsyncDisposableStack.prototype.defer requires that onAsyncDispose argument be a callable");

    @addDisposableResource(@getAsyncDisposableStackInternalField(this, @asyncDisposableStackFieldCapability), @undefined,  true, onAsyncDispose);

    return @undefined;
})
(function (onDispose)
{
    'use strict';

    if (!@isDisposableStack(this))
        @throwTypeError("DisposableStack.prototype.defer requires that |this| be a DisposableStack object");

    if (@getDisposableStackInternalField(this, @disposableStackFieldState) === @DisposableStackStateDisposed)
        throw new @ReferenceError("DisposableStack.prototype.defer requires that |this| be a pending DisposableStack object");

    if (!@isCallable(onDispose))
        @throwTypeError("DisposableStack.prototype.defer requires that onDispose argument be a callable");

    @addDisposableResource(@getDisposableStackInternalField(this, @disposableStackFieldCapability), @undefined,  false, onDispose);

    return @undefined;
})
(function (target, propertyKey)
{
    //
    //

    if (!@isObject(target))
        @throwTypeError("Reflect.deleteProperty requires the first argument be an object");

    return delete target[propertyKey];
})
(function (key)
{
    "use strict";

    var entry = this.registry.@get(key);
    if (!entry || !entry.evaluated)
        return null;

    var dependencies = entry.dependencies;
    var length = dependencies.length;
    var result = new @Array(length);
    for (var i = 0; i < length; ++i)
        result[i] = dependencies[i].key;

    return result;
})
(function ()
{
    'use strict';

    if (!@isDisposableStack(this))
        @throwTypeError("DisposableStack.prototype.dispose requires that |this| be a DisposableStack object");

    if (@getDisposableStackInternalField(this, @disposableStackFieldState) === @DisposableStackStateDisposed)
        return @undefined;

    @putDisposableStackInternalField(this, @disposableStackFieldState, @DisposableStackStateDisposed);

    var stack = @getDisposableStackInternalField(this, @disposableStackFieldCapability);
    @assert(@isArray(stack));

    var i = stack.length;
    var thrown = false;
    var suppressed;

    while (i) {
        var resource = stack[--i];
        try {
            resource.method.@call(resource.value);
        } catch (e) {
            if (thrown)
                suppressed = new @SuppressedError(e, suppressed);
            else {
                thrown = true;
                suppressed = e;
            }
        }
    }

    @putDisposableStackInternalField(this, @disposableStackFieldCapability, []);
    if (thrown)
        throw suppressed;
})
(function ()
{
    "use strict";

    var returnMethod = this.return;
    if (returnMethod !== @undefined)
        returnMethod.@call(this);
})
(function ()
{
    'use strict';

    var promiseCapability = @newPromiseCapability(@Promise);

    if (!@isAsyncDisposableStack(this)) {
        @rejectPromiseWithFirstResolvingFunctionCallCheck(promiseCapability.promise, @makeTypeError("AsyncDisposableStack.prototype.disposeAsync requires that |this| be a AsyncDisposableStack object"));
        return promiseCapability.promise;
    }

    if (@getAsyncDisposableStackInternalField(this, @asyncDisposableStackFieldState) === @AsyncDisposableStackStateDisposed) {
        @resolvePromiseWithFirstResolvingFunctionCallCheck(promiseCapability.promise, @undefined);
        return promiseCapability.promise;
    }

    @putAsyncDisposableStackInternalField(this, @asyncDisposableStackFieldState, @AsyncDisposableStackStateDisposed);

    var stack = @getAsyncDisposableStackInternalField(this, @asyncDisposableStackFieldCapability);
    @assert(@isArray(stack));

    var i = stack.length;
    var thrown = false;
    var suppressed;

    var handleError = (result) => {
        if (thrown)
            suppressed = new @SuppressedError(result, suppressed);
        else {
            thrown = true;
            suppressed = result;
        }
        loop();
    };

    var loop = () => {
        if (i) {
            var resource = stack[--i];
            try {
                @Promise.@resolve(resource.method.@call(resource.value)).@then(loop, handleError);
            } catch (error) {
                handleError(error);
            }
        } else {
            if (thrown)
                @rejectPromiseWithFirstResolvingFunctionCallCheck(promiseCapability.promise, suppressed);
            else
               @resolvePromiseWithFirstResolvingFunctionCallCheck(promiseCapability.promise, @undefined);
        }
    };

    loop();

    @putAsyncDisposableStackInternalField(this, @asyncDisposableStackFieldCapability, []);

    return promiseCapability.promise;
})
(function (generator, resumeValue, resumeMode)
{
    "use strict";

    if (resumeMode === @GeneratorResumeModeReturn && @isSuspendYieldState(generator)) {
        @putAsyncGeneratorInternalField(generator, @asyncGeneratorFieldSuspendReason, @AsyncGeneratorSuspendReasonAwait);
        @awaitValue(generator, resumeValue, @doAsyncGeneratorBodyCallOnFulfilledReturn);
        return;
    }

    var value = @undefined;
    var state = @getAsyncGeneratorInternalField(generator, @generatorFieldState);

    @putAsyncGeneratorInternalField(generator, @generatorFieldState, @AsyncGeneratorStateExecuting);
    @putAsyncGeneratorInternalField(generator, @asyncGeneratorFieldSuspendReason, @AsyncGeneratorSuspendReasonNone);

    try {
        value = @getAsyncGeneratorInternalField(generator, @generatorFieldNext).@call(@getAsyncGeneratorInternalField(generator, @generatorFieldThis), generator, state, resumeValue, resumeMode, @getAsyncGeneratorInternalField(generator, @generatorFieldFrame));
        state = @getAsyncGeneratorInternalField(generator, @generatorFieldState);
        if (state === @AsyncGeneratorStateExecuting) {
            @putAsyncGeneratorInternalField(generator, @generatorFieldState, @AsyncGeneratorStateCompleted);
            state = @AsyncGeneratorStateCompleted;
        }
    } catch (error) {
        @putAsyncGeneratorInternalField(generator, @generatorFieldState, @AsyncGeneratorStateCompleted);
        @putAsyncGeneratorInternalField(generator, @asyncGeneratorFieldSuspendReason, @AsyncGeneratorSuspendReasonNone);

        return @asyncGeneratorReject(generator, error);
    }

    var reason = @getAsyncGeneratorInternalField(generator, @asyncGeneratorFieldSuspendReason);
    if (reason === @AsyncGeneratorSuspendReasonAwait) {
        @awaitValue(generator, value, @doAsyncGeneratorBodyCallOnFulfilledNormal);
        return;
    }

    if (reason === @AsyncGeneratorSuspendReasonYield)
        return @asyncGeneratorYield(generator, value, resumeMode);

    if (state === @AsyncGeneratorStateCompleted) {
        @assert(@getAsyncGeneratorInternalField(generator, @generatorFieldState) == @AsyncGeneratorStateCompleted);
        @putAsyncGeneratorInternalField(generator, @asyncGeneratorFieldSuspendReason, @AsyncGeneratorSuspendReasonNone);
        return @asyncGeneratorResolve(generator, value, true);
    }
})
(function (result, generator)
{
    "use strict";

    @doAsyncGeneratorBodyCall(generator, result, @GeneratorResumeModeNormal);
})
(function (result, generator)
{
    "use strict";

    @doAsyncGeneratorBodyCall(generator, result, @GeneratorResumeModeReturn);
})
(function (limit)
{
    "use strict";

    if (!@isObject(this))
        @throwTypeError("Iterator.prototype.drop requires that |this| be an Object.");

    var numLimit;
    @ifAbruptCloseIterator(this, (numLimit = @toNumber(limit)));
    if (numLimit !== numLimit) {
        try {
            @iteratorGenericClose(this);
        } finally {
            @throwRangeError("Iterator.prototype.drop argument must not be NaN.");
        }
    }

    var intLimit = @toIntegerOrInfinity(numLimit);
    if (intLimit < 0) {
        try {
            @iteratorGenericClose(this);
        } finally {
            @throwRangeError("Iterator.prototype.drop argument must be non-negative.");
        }
    }

    var iterated = this;
    var iteratedNextMethod = iterated.next;

    var generator = (function*() {
        var remaining = intLimit;
        for (;;) {
            var result = @iteratorGenericNext(iteratedNextMethod, iterated);
            if (result.done)
                return;

            if (remaining > 0) {
                if (remaining !== @Infinity)
                    remaining--;
            } else {
                var value = result.value;
                @ifAbruptCloseIterator(iterated, (
                    yield value
                ));
            }
        }
    })();

    return @iteratorHelperCreate(generator, iterated);
})
(function (key)
{
    //

    "use strict";

    var entry = this.registry.@get(key);
    if (entry)
        return entry;

    entry = @newRegistryEntry(key);
    this.registry.@set(key, entry);

    return entry;
})
(function (sourceText)
{
    "use strict";

    if (!@isShadowRealm(this))
        @throwTypeError("`%ShadowRealm%.evaluate requires that |this| be a ShadowRealm instance");

    if (typeof sourceText !== 'string')
        @throwTypeError("`%ShadowRealm%.evaluate requires that the |sourceText| argument be a string");

    return @wrapRemoteValue(true, this, @evalInRealm(this, sourceText));
})
(function (callback )
{
    "use strict";

    var array = @toObject(this, "Array.prototype.every requires that |this| not be null or undefined");
    var length = @toLength(array.length);

    if (!@isCallable(callback))
        @throwTypeError("Array.prototype.every callback must be a function");
    
    var thisArg = @argument(1);
    
    for (var i = 0; i < length; i++) {
        if (!(i in array))
            continue;
        if (!callback.@call(thisArg, array[i], i, array))
            return false;
    }
    
    return true;
})
(function (predicate)
{
    "use strict";

    if (!@isObject(this))
        @throwTypeError("Iterator.prototype.every requires that |this| be an Object.");

    if (!@isCallable(predicate)) {
        try {
            @iteratorGenericClose(this);
        } finally {
            @throwTypeError("Iterator.prototype.every callback must be a function.");
        }
    }

    var iterated = this;
    var count = 0;
    var wrapper = { @@iterator: function () { return iterated; }};
    for (var item of wrapper) {
        if (!predicate(item, count++))
            return false;
    }

    return true;
})
(function (callback )
{
    "use strict";

    var array = @toObject(this, "Array.prototype.filter requires that |this| not be null or undefined");
    var length = @toLength(array.length);

    if (!@isCallable(callback))
        @throwTypeError("Array.prototype.filter callback must be a function");
    
    var thisArg = @argument(1);
    var result = @newArrayWithSpecies(0, array);

    var nextIndex = 0;
    for (var i = 0; i < length; i++) {
        if (!(i in array))
            continue;
        var current = array[i]
        if (callback.@call(thisArg, current, i, array)) {
            @putByValDirect(result, nextIndex, current);
            ++nextIndex;
        }
    }
    return result;
})
(function (predicate)
{
    "use strict";

    if (!@isObject(this))
        @throwTypeError("Iterator.prototype.filter requires that |this| be an Object.");

    if (!@isCallable(predicate)) {
        try {
            @iteratorGenericClose(this);
        } finally {
            @throwTypeError("Iterator.prototype.filter callback must be a function.");
        }
    }

    var iterated = this;
    var iteratedNextMethod = iterated.next;

    var generator = (function*() {
        var counter = 0;
        for (;;) {
            var result = @iteratorGenericNext(iteratedNextMethod, iterated);
            if (result.done)
                return;

            var value = result.value;
            @ifAbruptCloseIterator(iterated, (
                predicate(value, counter++) && (yield value)
            ));
        }
    })();

    return @iteratorHelperCreate(generator, iterated);
})
(function (onFinally)
{
    "use strict";

    if (!@isObject(this))
        @throwTypeError("|this| is not an object");

    var constructor = @speciesConstructor(this, @Promise);

    @assert(@isConstructor(constructor));

    var thenFinally;
    var catchFinally;

    if (!@isCallable(onFinally)) {
        thenFinally = onFinally;
        catchFinally = onFinally;
    } else {
        thenFinally = (0,  (value) => {
            @assert(@isCallable(onFinally));
            var result = onFinally();

            @assert(@isConstructor(constructor));
            var promise = @promiseResolve(constructor, result);

            return promise.then(() => value);
        });
        catchFinally = (0,  (reason) => {
            @assert(@isCallable(onFinally));
            var result = onFinally();

            @assert(@isConstructor(constructor));
            var promise = @promiseResolve(constructor, result);

            return promise.then(() => { throw reason; });
        });
    }

    return this.then(thenFinally, catchFinally);
})
(function (callback )
{
    "use strict";

    var array = @toObject(this, "Array.prototype.find requires that |this| not be null or undefined");
    var length = @toLength(array.length);

    if (!@isCallable(callback))
        @throwTypeError("Array.prototype.find callback must be a function");
    
    var thisArg = @argument(1);
    for (var i = 0; i < length; i++) {
        var kValue = array[i];
        if (callback.@call(thisArg, kValue, i, array))
            return kValue;
    }
    return @undefined;
})
(function (predicate)
{
    "use strict";

    if (!@isObject(this))
        @throwTypeError("Iterator.prototype.find requires that |this| be an Object.");

    if (!@isCallable(predicate)) {
        try {
            @iteratorGenericClose(this);
        } finally {
            @throwTypeError("Iterator.prototype.find callback must be a function.");
        }
    }

    var iterated = this;
    var count = 0;
    var wrapper = { @@iterator: function () { return iterated; }};
    for (var item of wrapper) {
        if (predicate(item, count++))
            return item;
    }

    return @undefined;
})
(function (callback )
{
    "use strict";

    var array = @toObject(this, "Array.prototype.findIndex requires that |this| not be null or undefined");
    var length = @toLength(array.length);

    if (!@isCallable(callback))
        @throwTypeError("Array.prototype.findIndex callback must be a function");
    
    var thisArg = @argument(1);
    for (var i = 0; i < length; i++) {
        if (callback.@call(thisArg, array[i], i, array))
            return i;
    }
    return -1;
})
(function (callback )
{
    "use strict";

    var array = @toObject(this, "Array.prototype.findLast requires that |this| not be null or undefined");
    var length = @toLength(array.length);

    if (!@isCallable(callback))
        @throwTypeError("Array.prototype.findLast callback must be a function");

    var thisArg = @argument(1);
    for (var i = length - 1; i >= 0; i--) {
        var element = array[i];
        if (callback.@call(thisArg, element, i, array))
            return element;
    }
    return @undefined;
})
(function (callback )
{
    "use strict";

    var array = @toObject(this, "Array.prototype.findLastIndex requires that |this| not be null or undefined");
    var length = @toLength(array.length);

    if (!@isCallable(callback))
        @throwTypeError("Array.prototype.findLastIndex callback must be a function");

    var thisArg = @argument(1);
    for (var i = length - 1; i >= 0; i--) {
        if (callback.@call(thisArg, array[i], i, array))
            return i;
    }
    return -1;
})
(function ()
{
    "use strict";
    return @createHTML("String.prototype.fixed", this, "tt", "", "");
})
(function ()
{
    "use strict";

    var array = @toObject(this, "Array.prototype.flat requires that |this| not be null or undefined");
    var length = @toLength(array.length);

    var depthNum = 1;
    var depth = @argument(0);
    if (depth !== @undefined)
        depthNum = @toIntegerOrInfinity(depth);

    var result = @newArrayWithSpecies(0, array);

    @flatIntoArray(result, array, length, 0, depthNum);
    return result;
})
(function (target, source, sourceLength, targetIndex, depth)
{
    "use strict";

    for (var sourceIndex = 0; sourceIndex < sourceLength; ++sourceIndex) {
        if (sourceIndex in source) {
            var element = source[sourceIndex];
            if (depth > 0 && @isArray(element))
                targetIndex = @flatIntoArray(target, element, @toLength(element.length), targetIndex, depth - 1);
            else {
                if (targetIndex >= @MAX_SAFE_INTEGER)
                    @throwTypeError("flatten array exceeds 2**53 - 1");
                @putByValDirect(target, targetIndex, element);
                ++targetIndex;
            }
        }
    }
    return targetIndex;
})
(function (target, source, sourceLength, targetIndex, callback, thisArg)
{
    "use strict";

    for (var sourceIndex = 0; sourceIndex < sourceLength; ++sourceIndex) {
        if (sourceIndex in source) {
            var element = callback.@call(thisArg, source[sourceIndex], sourceIndex, source);
            if (@isArray(element))
                targetIndex = @flatIntoArray(target, element, @toLength(element.length), targetIndex, 0);
            else {
                if (targetIndex >= @MAX_SAFE_INTEGER)
                    @throwTypeError("flatten array exceeds 2**53 - 1");
                @putByValDirect(target, targetIndex, element);
                ++targetIndex;
            }
        }
    }
    return target;
})
(function (callback)
{
    "use strict";

    var array = @toObject(this, "Array.prototype.flatMap requires that |this| not be null or undefined");
    var length = @toLength(array.length);

    if (!@isCallable(callback))
        @throwTypeError("Array.prototype.flatMap callback must be a function");

    var thisArg = @argument(1);

    var result = @newArrayWithSpecies(0, array);

    return @flatIntoArrayWithCallback(result, array, length, 0, callback, thisArg);
})
(function (mapper)
{
    "use strict";

    if (!@isObject(this))
        @throwTypeError("Iterator.prototype.flatMap requires that |this| be an Object.");

    if (!@isCallable(mapper)) {
        try {
            @iteratorGenericClose(this);
        } finally {
            @throwTypeError("Iterator.prototype.flatMap callback must be a function.");
        }
    }

    var iterated = this;
    var iteratedNextMethod = iterated.next;
    var iteratedWrapper = {
        @@iterator: function() { return this; },
        next: function() { return iteratedNextMethod.@call(iterated); },
        return: function() {
            var iteratedReturnMethod = iterated.return;
            if (iteratedReturnMethod !== @undefined)
                return iteratedReturnMethod.@call(iterated, @undefined);
            return { done: true };
        },
    };

    var generator = (function*() {
        var counter = 0;
        for (var item of iteratedWrapper) {
            var mapped = mapper(item, counter++);
            var innerIterator = @getIteratorFlattenable(mapped,  true);

            for (var innerItem of { @@iterator: function() { return innerIterator; } })
                yield innerItem;
        }
    })();

    return @iteratorHelperCreate(generator, iterated);
})
(function (color)
{
    "use strict";
    return @createHTML("String.prototype.fontcolor", this, "font", "color", color);
})
(function (size)
{
    "use strict";
    return @createHTML("String.prototype.fontsize", this, "font", "size", size);
})
(function (callback )
{
    "use strict";

    var array = @toObject(this, "Array.prototype.forEach requires that |this| not be null or undefined");
    var length = @toLength(array.length);

    if (!@isCallable(callback))
        @throwTypeError("Array.prototype.forEach callback must be a function");
    
    var thisArg = @argument(1);
    
    for (var i = 0; i < length; i++) {
        if (i in array)
            callback.@call(thisArg, array[i], i, array);
    }
})
(function (callback )
{
    "use strict";

    if (!@isMap(this))
        @throwTypeError("Map operation called on non-Map object");

    if (!@isCallable(callback))
        @throwTypeError("Map.prototype.forEach callback must be a function");

    var thisArg = @argument(1);
    var storage = @mapStorage(this);
    var entry = 0;

    do {
        storage = @mapIterationNext(storage, entry);
        if (storage == @orderedHashTableSentinel)
            return;
        entry = @mapIterationEntry(storage) + 1;
        callback.@call(thisArg, @mapIterationEntryValue(storage), @mapIterationEntryKey(storage), this);
    } while (true);
})
(function (callback )
{
    "use strict";

    if (!@isSet(this))
        @throwTypeError("Set operation called on non-Set object");

    if (!@isCallable(callback))
        @throwTypeError("Set.prototype.forEach callback must be a function");

    var thisArg = @argument(1);
    var storage = @setStorage(this);
    var entry = 0;

    do {
        storage = @setIterationNext(storage, entry);
        if (storage == @orderedHashTableSentinel)
            break;
        entry = @setIterationEntry(storage) + 1;
        var key = @setIterationEntryKey(storage);

        callback.@call(thisArg, key, key, this);
    } while (true);
})
(function (promise, value)
{
    "use strict";

    @assert(@isPromise(promise));

    if ((@getPromiseInternalField(promise, @promiseFieldFlags) & @promiseStateMask) === @promiseStatePending)
        @fulfillPromise(promise, value);
})
(function (items )
{
    "use strict";

    var mapFn = @argument(1);

    var thisArg;

    if (mapFn !== @undefined) {
        if (!@isCallable(mapFn))
            @throwTypeError("Array.from requires that the second argument, when provided, be a function");

        thisArg = @argument(2);
    }

    var arrayLike = @toObject(items, "Array.from requires an array-like object - not null or undefined");

    if (mapFn === @undefined) {
        var fastResult = @arrayFromFastFillWithUndefined(this, arrayLike);
        if (fastResult)
            return fastResult;
    }

    var iteratorMethod = items.@@iterator;
    if (!@isUndefinedOrNull(iteratorMethod)) {
        if (!@isCallable(iteratorMethod))
            @throwTypeError("Array.from requires that the property of the first argument, items[Symbol.iterator], when exists, be a function");

        var result = this !== @Array && @isConstructor(this) ? new this() : [];

        var k = 0;
        var iterator = iteratorMethod.@call(items);

        //
        //
        //
        var wrapper = {
            @@iterator: function () { return iterator; }
        };

        for (var value of wrapper) {
            if (k >= @MAX_SAFE_INTEGER)
                @throwTypeError("Length exceeded the maximum array length");
            if (mapFn === @undefined)
                @putByValDirect(result, k, value);
            else
                @putByValDirect(result, k, thisArg === @undefined ? mapFn(value, k) : mapFn.@call(thisArg, value, k));
            k += 1;
        }

        result.length = k;
        return result;
    }

    var arrayLikeLength = @toLength(arrayLike.length);

    var result = this !== @Array && @isConstructor(this) ? new this(arrayLikeLength) : @newArrayWithSize(arrayLikeLength);

    var k = 0;
    while (k < arrayLikeLength) {
        var value = arrayLike[k];
        if (mapFn === @undefined)
            @putByValDirect(result, k, value);
        else
            @putByValDirect(result, k, thisArg === @undefined ? mapFn(value, k) : mapFn.@call(thisArg, value, k));
        k += 1;
    }

    result.length = arrayLikeLength;
    return result;
})
(function (value)
{
    "use strict";

    //
    var iterator = @getIteratorFlattenable(value,  false);
    var iteratorNextMethod = iterator.next;
    //
    //
    //
    if (@instanceOf(iterator, @Iterator.prototype))
        return iterator;

    //
    //
    //
    return @wrapForValidIteratorCreate(iterator, iteratorNextMethod);
})
(function (items )
{
    "use strict";

    if (!@isConstructor(this))
        @throwTypeError("TypedArray.from requires |this| to be a constructor");

    var mapFn = @argument(1);
    var thisArg;
    if (mapFn !== @undefined) {
        if (!@isCallable(mapFn))
            @throwTypeError("TypedArray.from requires that the second argument, when provided, be a function");

        thisArg = @argument(2);
    }

    var arrayLike = @toObject(items, "TypedArray.from requires an array-like object - not null or undefined");

    if (mapFn === @undefined) {
        var fastResult = @typedArrayFromFast(this, arrayLike);
        if (fastResult)
            return fastResult;
    }

    var iteratorMethod = items.@@iterator;
    if (!@isUndefinedOrNull(iteratorMethod)) {
        if (!@isCallable(iteratorMethod))
            @throwTypeError("TypedArray.from requires that the property of the first argument, items[Symbol.iterator], when exists, be a function");

        var accumulator = [];

        var count = 0;
        var iterator = iteratorMethod.@call(items);

        //
        //
        //
        var wrapper = {};
        wrapper.@@iterator = function() { return iterator; }

        for (var value of wrapper) {
            @putByValDirect(accumulator, count, value);
            count++;
        }

        var result = new this(count);
        if (@typedArrayLength(result) < count)
            @throwTypeError("TypedArray.from constructed typed array of insufficient length");

        for (var k = 0; k < count; k++) {
            var value = accumulator[k];
            if (mapFn === @undefined)
                result[k] = value;
            else
                result[k] = thisArg === @undefined ? mapFn(value, k) : mapFn.@call(thisArg, value, k);
        }

        return result;
    }

    var arrayLikeLength = @toLength(arrayLike.length);

    var result = new this(arrayLikeLength);
    if (@typedArrayLength(result) < arrayLikeLength)
        @throwTypeError("TypedArray.from constructed typed array of insufficient length");

    for (var k = 0; k < arrayLikeLength; k++) {
        var value = arrayLike[k];
        if (mapFn === @undefined)
            result[k] = value;
        else
            result[k] = thisArg === @undefined ? mapFn(value, k) : mapFn.@call(thisArg, value, k);
    }

    return result;
})
(function (asyncItems  )
{
    "use strict";

    try {
        var mapFn = @argument(1);

        var thisArg;

        if (mapFn !== @undefined) {
            if (!@isCallable(mapFn))
                @throwTypeError("Array.fromAsync requires that the second argument, when provided, be a function");

            thisArg = @argument(2);
        }

        var usingSyncIterator;
        var usingAsyncIterator = asyncItems.@@asyncIterator;
        if (!@isUndefinedOrNull(usingAsyncIterator)) {
            if (!@isCallable(usingAsyncIterator))
                @throwTypeError("Array.fromAsync requires that the property of the first argument, items[Symbol.asyncIterator], when exists, be a function");
        } else {
            usingSyncIterator = asyncItems.@@iterator;
            if (!@isUndefinedOrNull(usingSyncIterator)) {
                if (!@isCallable(usingSyncIterator))
                    @throwTypeError("Array.fromAsync requires that the property of the first argument, items[Symbol.iterator], when exists, be a function");
            }
        }

        if (!@isUndefinedOrNull(usingAsyncIterator))
            return @defaultAsyncFromAsyncIterator.@call(this, usingAsyncIterator.@call(asyncItems), mapFn, thisArg);

        if (!@isUndefinedOrNull(usingSyncIterator)) {
            var iterator = usingSyncIterator.@call(asyncItems);
            return @defaultAsyncFromAsyncIterator.@call(this, @createAsyncFromSyncIterator(iterator, iterator.next), mapFn, thisArg);
        }

        return @defaultAsyncFromAsyncArrayLike.@call(this, asyncItems, mapFn, thisArg);
    } catch (reason) {
        var promise = @newPromise();
        @rejectPromiseWithFirstResolvingFunctionCallCheck(promise, reason);
        return promise;
    }
})
(function (iterable)
{
    "use strict";

    var object = {};

    for (var entry of iterable) {
        if (!@isObject(entry))
            @throwTypeError("Object.fromEntries requires the first iterable parameter yields objects");
        var key = entry[0];
        var value = entry[1];
        @putByValDirect(object, key, value);
    }

    return object;
})
(function (entry, source)
{
    //

    "use strict";

    if (!entry.fetch)
        entry.fetch = @newPromiseCapability(@InternalPromise).promise;
    @forceFulfillPromise(entry.fetch, source);
    @setStateToMax(entry, @ModuleInstantiate);
})
(function (promise, value)
{
    "use strict";

    @assert(@isPromise(promise));
    @assert((@getPromiseInternalField(promise, @promiseFieldFlags) & @promiseStateMask) == @promiseStatePending);

    var flags = @getPromiseInternalField(promise, @promiseFieldFlags);
    var reactions = @getPromiseInternalField(promise, @promiseFieldReactionsOrResult);
    @putPromiseInternalField(promise, @promiseFieldReactionsOrResult, value);
    @putPromiseInternalField(promise, @promiseFieldFlags, flags | @promiseStateFulfilled);

    @triggerPromiseReactions(@promiseStateFulfilled, reactions, value);
})
(function (promise, value)
{
    "use strict";

    @assert(@isPromise(promise));
    var flags = @getPromiseInternalField(promise, @promiseFieldFlags);
    if (flags & @promiseFlagsIsFirstResolvingFunctionCalled)
        return;
    @putPromiseInternalField(promise, @promiseFieldFlags, flags | @promiseFlagsIsFirstResolvingFunctionCalled);
    return @fulfillPromise(promise, value);
})
(function (value, onFulfilled, onRejected, context)
{
    "use strict";

    @enqueueJob(@promiseReactionJobWithoutPromise, onFulfilled, value, context, @getInternalField(@asyncContext, 0));
})
(function (generator, state, value, resumeMode)
{
    "use strict";

    @assert(state !== @GeneratorStateCompleted);

    if (state === @GeneratorStateExecuting)
        @throwTypeError("Generator is executing");

    @putGeneratorInternalField(generator, @generatorFieldState, @GeneratorStateExecuting);

    try {
        var value = @getGeneratorInternalField(generator, @generatorFieldNext).@call(@getGeneratorInternalField(generator, @generatorFieldThis), generator, state, value, resumeMode, @getGeneratorInternalField(generator, @generatorFieldFrame));
    } catch (error) {
        @putGeneratorInternalField(generator, @generatorFieldState, @GeneratorStateCompleted);
        throw error;
    }

    var done = @getGeneratorInternalField(generator, @generatorFieldState) === @GeneratorStateExecuting;
    if (done)
        @putGeneratorInternalField(generator, @generatorFieldState, @GeneratorStateCompleted);

    return { value, done };
})
(function (target, propertyKey )
{
    "use strict";

    if (!@isObject(target))
        @throwTypeError("Reflect.get requires the first argument be an object");

    if (@argumentCount() < 3)
        return target[propertyKey];

    var receiver = @argument(2);
    return @getByValWithThis(target, receiver, propertyKey);
})
(function (value)
{
    'use strict';

    var method = value.@@asyncDispose;

    if (!@isCallable(method))
        @throwTypeError("@@asyncDispose must be callable");

    if (@isUndefinedOrNull(method))
        return @undefined;

    return () => {
        var promiseCapability = @newPromiseCapability(@Promise);
        var result;
        try {
            result = method.@call(value);
        } catch (e) {
            @rejectPromiseWithFirstResolvingFunctionCallCheck(promiseCapability.promise, e);
            return promiseCapability.promise;
        }
        @resolvePromiseWithFirstResolvingFunctionCallCheck(promiseCapability.promise, @undefined);
        return promiseCapability.promise;
    };
})
(function (obj, rejectStrings)
{
    "use strict";

    //
    //
    if (!@isObject(obj) && (rejectStrings || typeof obj !== "string"))
        @throwTypeError("GetIteratorFlattenable expects its first argument to be an object" + (rejectStrings ? "" : " or a string"));
    //
    var method = obj.@@iterator;
    //
    //
    var iterator;
    if (@isUndefinedOrNull(method)) {
        iterator = obj;
        //
        //
    } else
        iterator = method.@call(obj);
    //
    if (!@isObject(iterator))
        @throwTypeError("Iterator is not an object");
    //
    return iterator;
})
(function (other)
{
    if (!@isObject(other))
        @throwTypeError("Set operation expects first argument to be an object");

    var size = @toNumber(other.size);
    if (size !== size) //
        @throwTypeError("Set operation expects first argument to have non-NaN 'size' property");

    var sizeInt = @toIntegerOrInfinity(size);
    if (sizeInt < 0)
        @throwRangeError("Set operation expects first argument to have non-negative 'size' property");

    return sizeInt;
})
(function (matched, str, position, captures, namedCaptures, replacement)
{
    "use strict";

    var matchLength = matched.length;
    var stringLength = str.length;
    var tailPos = position + matchLength;
    var m = captures.length;
    var replacementLength = replacement.length;
    var result = "";
    var lastStart = 0;

    for (var start = 0; start = @stringIndexOfInternal.@call(replacement, "$", lastStart), start !== -1; lastStart = start) {
        if (start - lastStart > 0)
            result = result + @stringSubstring.@call(replacement, lastStart, start);
        start++;
        if (start >= replacementLength)
            result = result + "$";
        else {
            var ch = replacement[start];
            switch (ch)
            {
            case "$":
                result = result + "$";
                start++;
                break;
            case "&":
                result = result + matched;
                start++;
                break;
            case "`":
                if (position > 0)
                    result = result + @stringSubstring.@call(str, 0, position);
                start++;
                break;
            case "'":
                if (tailPos < stringLength)
                    result = result + @stringSubstring.@call(str, tailPos);
                start++;
                break;
            case "<":
                if (namedCaptures !== @undefined) {
                    var groupNameStartIndex = start + 1;
                    var groupNameEndIndex = @stringIndexOfInternal.@call(replacement, ">", groupNameStartIndex);
                    if (groupNameEndIndex !== -1) {
                        var groupName = @stringSubstring.@call(replacement, groupNameStartIndex, groupNameEndIndex);
                        var capture = namedCaptures[groupName];
                        if (capture !== @undefined)
                            result = result + @toString(capture);

                        start = groupNameEndIndex + 1;
                        break;
                    }
                }

                result = result + "$<";
                start++;
                break;
            default:
                var chCode = ch.@charCodeAt(0);
                if (chCode >= 0x30 && chCode <= 0x39) {
                    var originalStart = start - 1;
                    start++;

                    var n = chCode - 0x30;
                    if (n > m) {
                        result = result + @stringSubstring.@call(replacement, originalStart, start);
                        break;
                    }

                    if (start < replacementLength) {
                        var nextChCode = replacement.@charCodeAt(start);
                        if (nextChCode >= 0x30 && nextChCode <= 0x39) {
                            var nn = 10 * n + nextChCode - 0x30;
                            if (nn <= m) {
                                n = nn;
                                start++;
                            }
                        }
                    }

                    if (n == 0) {
                        result = result + @stringSubstring.@call(replacement, originalStart, start);
                        break;
                    }

                    var capture = captures[n - 1];
                    if (capture !== @undefined)
                        result = result + capture;
                } else
                    result = result + "$";
                break;
            }
        }
    }

    return result + @stringSubstring.@call(replacement, lastStart);
})
(function (items, callback)
{
    "use strict";

    if (@isUndefinedOrNull(items))
        @throwTypeError("Map.groupBy requires that the first argument not be null or undefined");

    if (!@isCallable(callback))
        @throwTypeError("Map.groupBy requires that the second argument must be a function");

    var iteratorMethod = items.@@iterator;
    if (!@isCallable(iteratorMethod))
        @throwTypeError("Map.groupBy requires that the property of the first argument, items[Symbol.iterator] be a function");

    var groups = new @Map;
    var k = 0;

    var iterator = iteratorMethod.@call(items);
    //
    //
    //
    var wrapper = {
        @@iterator: function () { return iterator; }
    };
    for (var item of wrapper) {
        if (k >= @MAX_SAFE_INTEGER)
            @throwTypeError("The number of iterations exceeds 2**53 - 1");
        var key = callback.@call(@undefined, item, k);
        var group = groups.@get(key);
        if (!group) {
            group = [];
            groups.@set(key, group);
        }
        @putByValDirect(group, group.length, item);
        ++k;
    }
    return groups;
})
(function (items, callback)
{
    "use strict";

    if (@isUndefinedOrNull(items))
        @throwTypeError("Object.groupBy requires that the first argument not be null or undefined");

    if (!@isCallable(callback))
        @throwTypeError("Object.groupBy requires that the second argument must be a function");

    var iteratorMethod = items.@@iterator;
    if (!@isCallable(iteratorMethod))
        @throwTypeError("Object.groupBy requires that the property of the first argument, items[Symbol.iterator] be a function");

    var groups = @Object.@create(null);
    var k = 0;

    var iterator = iteratorMethod.@call(items);
    //
    //
    //
    var wrapper = {
        @@iterator: function () { return iterator; }
    };
    for (var item of wrapper) {
        if (k >= @MAX_SAFE_INTEGER)
            @throwTypeError("The number of iterations exceeds 2**53 - 1");
        var key = @toPropertyKey(callback.@call(@undefined, item, k));
        var group = groups[key];
        if (!group) {
            group = [];
            @putByValDirect(groups, key, group);
        }
        @putByValDirect(group, group.length, item);
        ++k;
    }
    return groups;
})
(function (target, propertyKey)
{
    "use strict";

    if (!@isObject(target))
        @throwTypeError("Reflect.has requires the first argument be an object");

    return propertyKey in target;
})
(function (regexp)
{
    "use strict";

    if (!@isRegExpObject(regexp))
        return true;

    //
    var regexpExec = @tryGetById(regexp, "exec");
    if (regexpExec !== @regExpBuiltinExec)
        return true;

    var regexpFlags = @tryGetById(regexp, "flags");
    if (regexpFlags !== @regExpProtoFlagsGetter)
        return true;

    //
    var regexpGlobal = @tryGetById(regexp, "global");
    if (regexpGlobal !== @regExpProtoGlobalGetter)
        return true;
    var regexpHasIndices = @tryGetById(regexp, "hasIndices");
    if (regexpHasIndices !== @regExpProtoHasIndicesGetter)
        return true;
    var regexpIgnoreCase = @tryGetById(regexp, "ignoreCase");
    if (regexpIgnoreCase !== @regExpProtoIgnoreCaseGetter)
        return true;
    var regexpMultiline = @tryGetById(regexp, "multiline");
    if (regexpMultiline !== @regExpProtoMultilineGetter)
        return true;
    var regexpSticky = @tryGetById(regexp, "sticky");
    if (regexpSticky !== @regExpProtoStickyGetter)
        return true;
    var regexpDotAll = @tryGetById(regexp, "dotAll");
    if (regexpDotAll !== @regExpProtoDotAllGetter)
        return true;
    var regexpUnicode = @tryGetById(regexp, "unicode");
    if (regexpUnicode !== @regExpProtoUnicodeGetter)
        return true;
    var regexpUnicodeSets = @tryGetById(regexp, "unicodeSets");
    if (regexpUnicodeSets !== @regExpProtoUnicodeSetsGetter)
        return true;

    return typeof regexp.lastIndex !== "number";
})
(function (regexp)
{
    "use strict";

    if (!@isRegExpObject(regexp))
        return true;

    //
    var regexpExec = @tryGetById(regexp, "exec");
    if (regexpExec !== @regExpBuiltinExec)
        return true;
    
    //
    var regexpFlags = @tryGetById(regexp, "flags");
    if (regexpFlags !== @regExpProtoFlagsGetter)
        return true;
    
    //
    var regexpGlobal = @tryGetById(regexp, "global");
    if (regexpGlobal !== @regExpProtoGlobalGetter)
        return true;
    var regexpHasIndices = @tryGetById(regexp, "hasIndices");
    if (regexpHasIndices !== @regExpProtoHasIndicesGetter)
        return true;
    var regexpIgnoreCase = @tryGetById(regexp, "ignoreCase");
    if (regexpIgnoreCase !== @regExpProtoIgnoreCaseGetter)
        return true;
    var regexpMultiline = @tryGetById(regexp, "multiline");
    if (regexpMultiline !== @regExpProtoMultilineGetter)
        return true;
    var regexpSticky = @tryGetById(regexp, "sticky");
    if (regexpSticky !== @regExpProtoStickyGetter)
        return true;
    var regexpDotAll = @tryGetById(regexp, "dotAll");
    if (regexpDotAll !== @regExpProtoDotAllGetter)
        return true;
    var regexpUnicode = @tryGetById(regexp, "unicode");
    if (regexpUnicode !== @regExpProtoUnicodeGetter)
        return true;
    var regexpUnicodeSets = @tryGetById(regexp, "unicodeSets");
    if (regexpUnicodeSets !== @regExpProtoUnicodeSetsGetter)
        return true;

    //
    var regexpSource = @tryGetById(regexp, "source");
    if (regexpSource !== @regExpProtoSourceGetter)
        return true;
    var regexpSymbolMatch = @tryGetByIdWithWellKnownSymbol(regexp, "match");
    if (regexpSymbolMatch !== @regExpPrototypeSymbolMatch)
        return true;

    return typeof regexp.lastIndex !== "number";
})
(function (regexp, replacer)
{
    "use strict";

    if (!@isRegExpObject(regexp))
        return true;

    if (replacer !== @regExpPrototypeSymbolReplace)
        return true;
    
    var regexpExec = @tryGetById(regexp, "exec");
    if (regexpExec !== @regExpBuiltinExec)
        return true;

    var regexpFlags = @tryGetById(regexp, "flags");
    if (regexpFlags !== @regExpProtoFlagsGetter)
        return true;

    //
    var regexpDotAll = @tryGetById(regexp, "dotAll");
    if (regexpDotAll !== @regExpProtoDotAllGetter)
        return true;
    var regexpGlobal = @tryGetById(regexp, "global");
    if (regexpGlobal !== @regExpProtoGlobalGetter)
        return true;
    var regexpHasIndices = @tryGetById(regexp, "hasIndices");
    if (regexpHasIndices !== @regExpProtoHasIndicesGetter)
        return true;
    var regexpIgnoreCase = @tryGetById(regexp, "ignoreCase");
    if (regexpIgnoreCase !== @regExpProtoIgnoreCaseGetter)
        return true;
    var regexpMultiline = @tryGetById(regexp, "multiline");
    if (regexpMultiline !== @regExpProtoMultilineGetter)
        return true;
    var regexpSticky = @tryGetById(regexp, "sticky");
    if (regexpSticky !== @regExpProtoStickyGetter)
        return true;
    var regexpUnicode = @tryGetById(regexp, "unicode");
    if (regexpUnicode !== @regExpProtoUnicodeGetter)
        return true;
    var regexpUnicodeSets = @tryGetById(regexp, "unicodeSets");
    if (regexpUnicodeSets !== @regExpProtoUnicodeSetsGetter)
        return true;

    return typeof regexp.lastIndex !== "number";
})
(function (specifier, exportName)
{
    "use strict";

    if (!@isShadowRealm(this))
        @throwTypeError("`%ShadowRealm%.importValue requires that |this| be a ShadowRealm instance");

    var specifierString = @toString(specifier);

    if (typeof exportName !== 'string')
        @throwTypeError("`%ShadowRealm%.importValue requires that the |exportName| argument be a string");

    var lookupBinding = (module) => {
        var lookup = module[exportName]
        if (lookup === @undefined)
            @throwTypeError("%ShadowRealm%.importValue requires |exportName| to exist in the |specifier|");

        return @wrapRemoteValue(true, this, lookup);
    };

    return @importInRealm(this, specifierString).@then(lookupBinding, @crossRealmThrow);
})
(function (source) {
    "use strict";

    var importObject = @argument(1);
    return @Promise.@resolve(source).@then((source) => {
        return @webAssemblyInstantiateStreamingInternal(source, importObject);
    });
})
(function (array)
{
    //
    //
    //
    //
    //
    //
    //
    //

    "use strict";

    var constructor = @InternalPromise;
    var promise = @createPromise(constructor,  true);
    var reject = (reason) => {
        return @rejectPromiseWithFirstResolvingFunctionCallCheck(promise, reason);
    };

    var values = [];
    var index = 0;
    var remainingElementsCount = 0;

    try {
        if (array.length === 0)
            @fulfillPromiseWithFirstResolvingFunctionCallCheck(promise, values);
        else {
            for (var index = 0, length = array.length; index < length; ++index) {
                var value = array[index];
                @putByValDirect(values, index, @undefined);
                let currentIndex = index;
                ++remainingElementsCount;
                @resolveWithoutPromise(value, (argument) => {
                    if (currentIndex < 0)
                        return @undefined;

                    @putByValDirect(values, currentIndex, argument);
                    currentIndex = -1;

                    --remainingElementsCount;
                    if (remainingElementsCount === 0)
                        return @fulfillPromiseWithFirstResolvingFunctionCallCheck(promise, values);

                    return @undefined;
                }, reject, @undefined);
            }
        }
    } catch (error) {
        reject(error);
    }

    return promise;
})
(function (array)
{
    "use strict";

    if (@isJSArray(array) || @isDerivedArray(array))
        return true;
    if (!@isProxyObject(array))
        return false;
    return @isArraySlow(array);
})
(function (generator)
{
    "use strict";

    var state = @getAsyncGeneratorInternalField(generator, @generatorFieldState);
    var reason = @getAsyncGeneratorInternalField(generator, @asyncGeneratorFieldSuspendReason);
    return (state > 0 && reason === @AsyncGeneratorSuspendReasonNone)
        || state === @AsyncGeneratorStateExecuting
        || reason === @AsyncGeneratorSuspendReasonAwait;
})
(function (generator)
{
    "use strict";

    var state = @getAsyncGeneratorInternalField(generator, @generatorFieldState);
    return (state > 0 && @getAsyncGeneratorInternalField(generator, @asyncGeneratorFieldSuspendReason) === @AsyncGeneratorSuspendReasonYield)
        || state === @AsyncGeneratorStateSuspendedYield;
})
(function ()
{
    "use strict";
    return @createHTML("String.prototype.italics", this, "i", "", "");
})
(function (entry, fetcher)
{
    //

    "use strict";

    if (entry.state < @ModuleLink)
        @throwTypeError("Requested module is not instantiated yet.");
    if (!entry.linkSucceeded)
        throw entry.linkError;
    if (entry.state === @ModuleReady)
        return;
    @setStateToMax(entry, @ModuleReady);

    try {
        //
        //
        //
        var hasAsyncDependency = false;
        var dependencies = entry.dependencies;
        for (var i = 0, length = dependencies.length; i < length; ++i) {
            var dependency = dependencies[i];
            this.link(dependency, fetcher);
            hasAsyncDependency ||= dependency.isAsync;
        }

        entry.isAsync = this.moduleDeclarationInstantiation(entry.module, fetcher) || hasAsyncDependency;
    } catch (error) {
        entry.linkSucceeded = false;
        entry.linkError = error;
        throw error;
    }
})
(function (url)
{
    "use strict";
    return @createHTML("String.prototype.link", this, "a", "href", url)
})
(function (key, fetcher)
{
    "use strict";

    var entry = this.ensureRegistered(key);
    this.link(entry, fetcher);
    return this.moduleEvaluation(entry, fetcher);
})
(async function (moduleName, parameters, fetcher)
{
    "use strict";

    var key = this.resolve(moduleName, @undefined, fetcher);
    key = await this.loadModule(key, parameters, fetcher);
    return await this.linkAndEvaluateModule(key, fetcher);
})
(async function (key, parameters, fetcher)
{
    "use strict";

    var entry = await this.requestSatisfy(this.ensureRegistered(key), parameters, fetcher, new @Set);
    return entry.key;
})
(function (callback )
{
    "use strict";

    var array = @toObject(this, "Array.prototype.map requires that |this| not be null or undefined");
    var length = @toLength(array.length);

    if (!@isCallable(callback))
        @throwTypeError("Array.prototype.map callback must be a function");
    
    var thisArg = @argument(1);
    var result = @newArrayWithSpecies(length, array);

    for (var i = 0; i < length; i++) {
        if (!(i in array))
            continue;
        var mappedValue = callback.@call(thisArg, array[i], i, array);
        @putByValDirect(result, i, mappedValue);
    }
    return result;
})
(function (mapper)
{
    "use strict";

    if (!@isObject(this))
        @throwTypeError("Iterator.prototype.map requires that |this| be an Object.");

    if (!@isCallable(mapper)) {
        try {
            @iteratorGenericClose(this);
        } finally {
            @throwTypeError("Iterator.prototype.map callback must be a function.");
        }
    }

    var iterated = this;
    var iteratedNextMethod = iterated.next;

    var generator = (function*() {
        var counter = 0;
        for (;;) {
            var result = @iteratorGenericNext(iteratedNextMethod, iterated);
            if (result.done)
                return;

            var value = result.value;
            @ifAbruptCloseIterator(iterated, (
                yield mapper(value, counter++)
            ));
        }
    })();

    return @iteratorHelperCreate(generator, iterated);
})
(function (strArg)
{
    "use strict";

    if (!@isObject(this))
        @throwTypeError("RegExp.prototype.@@match requires that |this| be an Object");

    var str = @toString(strArg);

    //
    if (!@hasObservableSideEffectsForRegExpMatch(this))
        return @regExpMatchFast.@call(this, str);
    return @matchSlow(this, str);
})
(function (regexp)
{
    "use strict";

    if (@isUndefinedOrNull(this))
        @throwTypeError("String.prototype.match requires that |this| not be null or undefined");

    if (@isObject(regexp)) {
        var matcher = regexp.@@match;
        if (!@isUndefinedOrNull(matcher))
            return matcher.@call(regexp, this);
    }

    var thisString = @toString(this);
    var createdRegExp = @regExpCreate(regexp, @undefined);
    return createdRegExp.@@match(thisString);
})
(function (strArg)
{
    "use strict";

    var regExp = this;
    if (!@isObject(regExp))
        @throwTypeError("RegExp.prototype.@@matchAll requires |this| to be an Object");

    var string = @toString(strArg);
    var Matcher = @speciesConstructor(regExp, @RegExp);

    var flags = @toString(regExp.flags);
    var matcher = new Matcher(regExp, flags);
    matcher.lastIndex = @toLength(regExp.lastIndex);

    var global = @stringIncludesInternal.@call(flags, "g");
    var fullUnicode = @stringIncludesInternal.@call(flags, "u") || @stringIncludesInternal.@call(flags, "v");

    return @regExpStringIteratorCreate(matcher, string, global, fullUnicode);
})
(function (arg)
{
    "use strict";

    if (@isUndefinedOrNull(this))
        @throwTypeError("String.prototype.matchAll requires |this| not to be null nor undefined");

    if (@isObject(arg)) {
        if (@isRegExp(arg) && !@stringIncludesInternal.@call(@toString(arg.flags), "g"))
            @throwTypeError("String.prototype.matchAll argument must not be a non-global regular expression");

        var matcher = arg.@@matchAll;
        if (!@isUndefinedOrNull(matcher))
            return matcher.@call(arg, this);
    }

    var string = @toString(this);
    var regExp = @regExpCreate(arg, "g");
    return regExp.@@matchAll(string);
})
(function (regexp, str)
{
    "use strict";

    var flags = @toString(regexp.flags);
    var global = @stringIncludesInternal.@call(flags, "g");

    if (!global)
        return @regExpExec(regexp, str);
    
    var unicode = @stringIncludesInternal.@call(flags, "u") || @stringIncludesInternal.@call(flags, "v");
    regexp.lastIndex = 0;
    var resultList = [];

    //
    //
    //
    var maximumReasonableMatchSize = 100000000;

    while (true) {
        var result = @regExpExec(regexp, str);
        
        if (result === null) {
            if (resultList.length === 0)
                return null;
            return resultList;
        }

        if (resultList.length > maximumReasonableMatchSize)
            @throwOutOfMemoryError();

        var resultString = @toString(result[0]);

        if (!resultString.length)
            regexp.lastIndex = @advanceStringIndex(str, regexp.lastIndex, unicode);

        @arrayPush(resultList, resultString);
    }
})
(function (entry, fetcher)
{
    //
    "use strict";

    if (entry.evaluated)
        return;
    entry.evaluated = true;

    //
    var dependencies = entry.dependencies;

    if (!entry.isAsync) {
        //
        for (var i = 0, length = dependencies.length; i < length; ++i) {
            var dependency = dependencies[i];
            @assert(!dependency.isAsync);
            this.moduleEvaluation(dependency, fetcher);
        }

        this.evaluate(entry.key, entry.module, fetcher);
    } else
        return this.asyncModuleEvaluation(entry, fetcher, dependencies);
})
(function ()
{
    'use strict';

    if (!@isAsyncDisposableStack(this))
        @throwTypeError("AsyncDisposableStack.prototype.move requires that |this| be a AsyncDisposableStack object");

    if (@getAsyncDisposableStackInternalField(this, @asyncDisposableStackFieldState) === @AsyncDisposableStackStateDisposed)
        throw new @ReferenceError("AsyncDisposableStack.prototype.move requires that |this| be a pending AsyncDisposableStack object");

    var newAsyncDisposableStack = new @AsyncDisposableStack();
    @putAsyncDisposableStackInternalField(newAsyncDisposableStack, @asyncDisposableStackFieldCapability, @getAsyncDisposableStackInternalField(this, @asyncDisposableStackFieldCapability));

    @putAsyncDisposableStackInternalField(this, @asyncDisposableStackFieldCapability, []);
    @putAsyncDisposableStackInternalField(this, @asyncDisposableStackFieldState, @AsyncDisposableStackStateDisposed);

    return newAsyncDisposableStack;
})
(function ()
{
    'use strict';

    if (!@isDisposableStack(this))
        @throwTypeError("DisposableStack.prototype.move requires that |this| be a DisposableStack object");

    if (@getDisposableStackInternalField(this, @disposableStackFieldState) === @DisposableStackStateDisposed)
        throw new @ReferenceError("DisposableStack.prototype.move requires that |this| be a pending DisposableStack object");

    var newDisposableStack = new @DisposableStack();
    @putDisposableStackInternalField(newDisposableStack, @disposableStackFieldCapability, @getDisposableStackInternalField(this, @disposableStackFieldCapability));

    @putDisposableStackInternalField(this, @disposableStackFieldCapability, []);
    @putDisposableStackInternalField(this, @disposableStackFieldState, @DisposableStackStateDisposed);

    return newDisposableStack;
})
(function (error)
{
    "use strict";
    var promise = @newPromise();
    @rejectPromiseWithFirstResolvingFunctionCallCheck(promise, error);
    @putPromiseInternalField(promise, @promiseFieldFlags, @getPromiseInternalField(promise, @promiseFieldFlags) | @promiseFlagsIsHandled);
    return promise;
})
(function (constructor)
{
    "use strict";

    if (constructor === @Promise) {
        var promise = @newPromise();
        var capturedPromise = promise;
        function @resolve(resolution) {
            return @resolvePromiseWithFirstResolvingFunctionCallCheck(capturedPromise, resolution);
        }
        function @reject(reason) {
            return @rejectPromiseWithFirstResolvingFunctionCallCheck(capturedPromise, reason);
        }
        return { resolve: @resolve, reject: @reject, promise };
    }

    return @newPromiseCapabilitySlow(constructor);
})
(function (constructor)
{
    "use strict";

    var promiseCapability = {
        resolve: @undefined,
        reject: @undefined,
        promise: @undefined,
    };

    var promise = new constructor((resolve, reject) => {
        if (promiseCapability.resolve !== @undefined)
            @throwTypeError("resolve function is already set");
        if (promiseCapability.reject !== @undefined)
            @throwTypeError("reject function is already set");

        promiseCapability.resolve = resolve;
        promiseCapability.reject = reject;
    });

    if (!@isCallable(promiseCapability.resolve))
        @throwTypeError("executor did not take a resolve function");

    if (!@isCallable(promiseCapability.reject))
        @throwTypeError("executor did not take a reject function");

    promiseCapability.promise = promise;

    return promiseCapability;
})
(function (key)
{
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //

    "use strict";

    return {
        key: key,
        state: @ModuleFetch,
        fetch: @undefined,
        instantiate: @undefined,
        satisfy: @undefined,
        isSatisfied: false,
        dependencies: [], //
        module: @undefined, //
        linkError: @undefined,
        linkSucceeded: true,
        evaluated: false,
        then: @undefined,
        isAsync: false,
    };
})
(function ()
{
    "use strict";

    if (!@isArrayIterator(this))
        @throwTypeError("%ArrayIteratorPrototype%.next requires that |this| be an Array Iterator instance");

    var array = @getArrayIteratorInternalField(this, @arrayIteratorFieldIteratedObject);
    if (@isTypedArrayView(array) && @isDetached(array))
        @throwTypeError("Underlying ArrayBuffer has been detached from the view or out-of-bounds");

    var kind = @getArrayIteratorInternalField(this, @arrayIteratorFieldKind);
    return @arrayIteratorNextHelper.@call(this, array, kind);
})
(function (value)
{
    "use strict";

    @assert(@isAsyncFromSyncIterator(this));

    var promise = @newPromise();

    if (!@isObject(this) || !@isObject(@getAsyncFromSyncIteratorInternalField(this, @asyncFromSyncIteratorFieldSyncIterator))) {
        @rejectPromiseWithFirstResolvingFunctionCallCheck(promise, @makeTypeError('Iterator is not an object.'));
        return promise;
    }

    var syncIterator = @getAsyncFromSyncIteratorInternalField(this, @asyncFromSyncIteratorFieldSyncIterator);
    var nextMethod = @getAsyncFromSyncIteratorInternalField(this, @asyncFromSyncIteratorFieldNextMethod);

    try {
        var nextResult = @argumentCount() === 0 ? nextMethod.@call(syncIterator) : nextMethod.@call(syncIterator, value);
        var onFulfilled = nextResult.done ? @asyncFromSyncIteratorOnFulfilledDone : @asyncFromSyncIteratorOnFulfilledContinue;
        @resolveWithoutPromiseForAsyncAwait(nextResult.value, onFulfilled, @asyncFromSyncIteratorOnRejected, { @promise: promise, @syncIterator: syncIterator });
    } catch (e) {
        @rejectPromiseWithFirstResolvingFunctionCallCheck(promise, e);
    }

    return promise;
})
(function (value)
{
    "use strict";

    return @asyncGeneratorEnqueue(this, value, @GeneratorResumeModeNormal);
})
(function (value)
{
    "use strict";

    if (!@isGenerator(this))
        @throwTypeError("|this| should be a generator");

    var state = @getGeneratorInternalField(this, @generatorFieldState);
    if (state === @GeneratorStateCompleted)
        return { value: @undefined, done: true };

    return @generatorResume(this, state, value, @GeneratorResumeModeNormal);
})
(function ()
{
    "use strict";

    if (!@isIteratorHelper(this))
        @throwTypeError("|this| should be an iterator helper");

    var generator = @getIteratorHelperInternalField(this, @iteratorHelperFieldGenerator);
    var state = @getGeneratorInternalField(generator, @generatorFieldState);
    if (state === @GeneratorStateCompleted)
        return { value: @undefined, done: true };

    return @generatorResume(generator, state, @undefined, @GeneratorResumeModeNormal);
})
(function () {
    "use strict";

    if (!@isMapIterator(this))
        @throwTypeError("%MapIteratorPrototype%.next requires that |this| be an Map Iterator instance");

    var value;
    var done = @mapIteratorNext(this);

    if (!done) {
        var kind = @getMapIteratorInternalField(this, @mapIteratorFieldKind);
        if (kind === @iterationKindKey)
            value = @mapIteratorKey(this);
        else if (kind === @iterationKindValue)
            value = @mapIteratorValue(this);
        else
            value = [@mapIteratorKey(this), @mapIteratorValue(this)];
    }
    return { value, done };
})
(function ()
{
    "use strict";

    if (!@isObject(this))
        @throwTypeError("%RegExpStringIteratorPrototype%.next requires |this| to be an Object");

    if (!@isRegExpStringIterator(this))
        @throwTypeError("%RegExpStringIteratorPrototype%.next requires |this| to be an RegExp String Iterator instance");

    var done = @getRegExpStringIteratorInternalField(this, @regExpStringIteratorFieldDone);
    if (done)
        return { value: @undefined, done: true };

    var regExp = @getRegExpStringIteratorInternalField(this, @regExpStringIteratorFieldRegExp);
    var string = @getRegExpStringIteratorInternalField(this, @regExpStringIteratorFieldString);
    var global = @getRegExpStringIteratorInternalField(this, @regExpStringIteratorFieldGlobal);
    var fullUnicode = @getRegExpStringIteratorInternalField(this, @regExpStringIteratorFieldFullUnicode);
    var match = @regExpExec(regExp, string);
    if (match === null) {
        @putRegExpStringIteratorInternalField(this, @regExpStringIteratorFieldDone, true);
        return { value: @undefined, done: true };
    }

    if (global) {
        var matchStr = @toString(match[0]);
        if (matchStr === "") {
            var thisIndex = @toLength(regExp.lastIndex);
            regExp.lastIndex = @advanceStringIndex(string, thisIndex, fullUnicode);
        }
    } else
        @putRegExpStringIteratorInternalField(this, @regExpStringIteratorFieldDone, true);

    return { value: match, done: false };
})
(function () {
    "use strict";

    if (!@isSetIterator(this))
        @throwTypeError("%SetIteratorPrototype%.next requires that |this| be a Set Iterator instance");

    var value;
    var done = @setIteratorNext(this);

    if (!done) {
        var kind = @getSetIteratorInternalField(this, @setIteratorFieldKind);
        var value = @setIteratorKey(this);
        if (kind === @iterationKindEntries)
            value = [value, value];
    }
    return { value, done };
})
(function ()
{
    "use strict";

    if (!@isStringIterator(this))
        @throwTypeError("%StringIteratorPrototype%.next requires that |this| be a String Iterator instance");

    var done = true;
    var value = @undefined;

    var position = @getStringIteratorInternalField(this, @stringIteratorFieldIndex);
    if (position !== -1) {
        var string = @getStringIteratorInternalField(this, @stringIteratorFieldIteratedString);
        var length = string.length >>> 0;
        if (position >= length)
            @putStringIteratorInternalField(this, @stringIteratorFieldIndex, -1);
        else {
            done = false;

            var first = string.@charCodeAt(position);
            if (first < 0xD800 || first > 0xDBFF || position + 1 === length)
                value = string[position];
            else {
                var second = string.@charCodeAt(position + 1);
                if (second < 0xDC00 || second > 0xDFFF)
                    value = string[position];
                else
                    value = string[position] + string[position + 1];
            }
            @putStringIteratorInternalField(this, @stringIteratorFieldIndex, position + value.length);
        }
    }

    return { value, done };
})
(function ()
{
    "use strict";

    //
    //
    //
    if (!@isWrapForValidIterator(this))
        @throwTypeError("%WrapForValidIteratorPrototype%.next requires that |this| be a WrapForValidIteratorPrototype object");

    //
    return @getWrapForValidIteratorInternalField(this, @wrapForValidIteratorFieldIteratedNextMethod).@call(@getWrapForValidIteratorInternalField(this, @wrapForValidIteratorFieldIteratedIterator));
})
(function ()
{
    "use strict";

    var length = @argumentCount();
    var array = this !== @Array && @isConstructor(this) ? new this(length) : @newArrayWithSize(length);
    for (var k = 0; k < length; ++k)
        @putByValDirect(array, k, arguments[k]);
    array.length = length;
    return array;
})
(function ()
{
    "use strict";
    var len = @argumentCount();

    if (!@isConstructor(this))
        @throwTypeError("TypedArray.of requires |this| to be a constructor");

    var result = new this(len);
    if (@typedArrayLength(result) < len)
        @throwTypeError("TypedArray.of constructed typed array of insufficient length");

    for (var i = 0; i < len; i++)
        result[i] = arguments[i];

    return result;
})
(function (maxLength)
{
    "use strict";

    if (@isUndefinedOrNull(this))
        @throwTypeError("String.prototype.padEnd requires that |this| not be null or undefined");

    var string = @toString(this);
    maxLength = @toLength(maxLength);

    var stringLength = string.length;
    if (maxLength <= stringLength)
        return string;

    var filler;
    var fillString = @argument(1);
    if (fillString === @undefined)
        filler = " ";
    else {
        filler = @toString(fillString);
        if (filler === "")
            return string;
    }

    if (maxLength > @MAX_STRING_LENGTH)
        @throwOutOfMemoryError();

    var fillLength = maxLength - stringLength;
    var truncatedStringFiller;

    if (filler.length === 1)
        truncatedStringFiller = @repeatCharacter(filler, fillLength);
    else
        truncatedStringFiller = @repeatCharactersSlowPath(filler, fillLength);
    return string + truncatedStringFiller;
})
(function (maxLength)
{
    "use strict";

    if (@isUndefinedOrNull(this))
        @throwTypeError("String.prototype.padStart requires that |this| not be null or undefined");

    var string = @toString(this);
    maxLength = @toLength(maxLength);

    var stringLength = string.length;
    if (maxLength <= stringLength)
        return string;

    var filler;
    var fillString = @argument(1);
    if (fillString === @undefined)
        filler = " ";
    else {
        filler = @toString(fillString);
        if (filler === "")
            return string;
    }

    if (maxLength > @MAX_STRING_LENGTH)
        @throwOutOfMemoryError();

    var fillLength = maxLength - stringLength;
    var truncatedStringFiller;

    if (filler.length === 1)
        truncatedStringFiller = @repeatCharacter(filler, fillLength);
    else
        truncatedStringFiller = @repeatCharactersSlowPath(filler, fillLength);
    return truncatedStringFiller + string;
})
(function (iterable)
{
    "use strict";
    //
    //
    //

    var result = [];
    if (@isUndefinedOrNull(iterable))
        @throwTypeError('Spread syntax requires ...iterable not be null or undefined');
    
    var iteratorMethod = iterable.@@iterator;
    if (!@isCallable(iteratorMethod))
        @throwTypeError('Spread syntax requires ...iterable[Symbol.iterator] to be a function');

    var iterator = iteratorMethod.@call(iterable);
    var next = iterator.next;
    var item;
    var index = 0;
    while (true) {
        item = next.@call(iterator);
        if (!@isObject(item))
            @throwTypeError("Iterator result interface is not an object");
        if (item.done)
            return result;
        @putByValDirect(result, index++, item.value);
    }
})
(function (promise, onFulfilled, onRejected, promiseOrCapability, context)
{
    "use strict";

    if (!@isCallable(onFulfilled))
        onFulfilled = @promiseEmptyOnFulfilled;

    if (!@isCallable(onRejected))
        onRejected = @promiseEmptyOnRejected;

    var reactionsOrResult = @getPromiseInternalField(promise, @promiseFieldReactionsOrResult);
    var flags = @getPromiseInternalField(promise, @promiseFieldFlags);
    var state = flags & @promiseStateMask;
    if (state === @promiseStatePending)
        @pushNewPromiseReaction(promise, reactionsOrResult, promiseOrCapability, onFulfilled, onRejected, context);
    else {
        var handler;

        if (state === @promiseStateRejected) {
            handler = onRejected;
            if (!(flags & @promiseFlagsIsHandled))
                @hostPromiseRejectionTracker(promise, @promiseRejectionHandle);
        } else
            handler = onFulfilled;
        var asyncContext = @getInternalField(@asyncContext, 0);
        @enqueueJob(@promiseReactionJob, promiseOrCapability, handler, reactionsOrResult, asyncContext ? [context, asyncContext] : context);
    }
    @putPromiseInternalField(promise, @promiseFieldFlags, @getPromiseInternalField(promise, @promiseFieldFlags) | @promiseFlagsIsHandled);
})
(function (propertyName, receiver)
{
    "use strict";

    var target = @getProxyInternalField(this, @proxyFieldTarget);
    var handler = @getProxyInternalField(this, @proxyFieldHandler);

    if (handler === null)
        @throwTypeError("Proxy has already been revoked. No more operations are allowed to be performed on it");

    var trap = handler.get;
    if (@isUndefinedOrNull(trap))
        return @getByValWithThis(target, receiver, propertyName);

    if (!@isCallable(trap))
        @throwTypeError("'get' property of a Proxy's handler should be callable");

    var trapResult = trap.@call(handler, target, propertyName, @toThis(receiver));

    if (@mustValidateResultOfProxyGetAndSetTraps(target))
        @handleProxyGetTrapResult(trapResult, target, propertyName);

    return trapResult;
})
(function (propertyName, receiver)
{
    "use strict";

    var target = @getProxyInternalField(this, @proxyFieldTarget);
    var handler = @getProxyInternalField(this, @proxyFieldHandler);
    var propertyName = @toPropertyKey(propertyName);

    if (handler === null)
        @throwTypeError("Proxy has already been revoked. No more operations are allowed to be performed on it");

    var trap = handler.get;
    if (@isUndefinedOrNull(trap))
        return @getByValWithThis(target, receiver, propertyName);

    if (!@isCallable(trap))
        @throwTypeError("'get' property of a Proxy's handler should be callable");

    var trapResult = trap.@call(handler, target, propertyName, @toThis(receiver));

    if (@mustValidateResultOfProxyGetAndSetTraps(target))
        @handleProxyGetTrapResult(trapResult, target, propertyName);

    return trapResult;
})
(function (propertyName)
{
    "use strict";

    var target = @getProxyInternalField(this, @proxyFieldTarget);
    var handler = @getProxyInternalField(this, @proxyFieldHandler);

    if (handler === null)
        @throwTypeError("Proxy has already been revoked. No more operations are allowed to be performed on it");

    var trap = handler.has;
    if (@isUndefinedOrNull(trap))
        return propertyName in target;

    if (!@isCallable(trap))
        @throwTypeError("'has' property of a Proxy's handler should be callable");

    if (trap.@call(handler, target, propertyName))
        return true;

    if (@mustValidateResultOfProxyTrapsExceptGetAndSet(target))
        @handleNegativeProxyHasTrapResult(target, propertyName);

    return false;
})
(function (propertyName)
{
    "use strict";

    var target = @getProxyInternalField(this, @proxyFieldTarget);
    var handler = @getProxyInternalField(this, @proxyFieldHandler);
    var propertyName = @toPropertyKey(propertyName);

    if (handler === null)
        @throwTypeError("Proxy has already been revoked. No more operations are allowed to be performed on it");

    var trap = handler.has;
    if (@isUndefinedOrNull(trap))
        return propertyName in target;

    if (!@isCallable(trap))
        @throwTypeError("'has' property of a Proxy's handler should be callable");

    if (trap.@call(handler, target, propertyName))
        return true;

    if (@mustValidateResultOfProxyTrapsExceptGetAndSet(target))
        @handleNegativeProxyHasTrapResult(target, propertyName);

    return false;
})
(function (propertyName, receiver, value)
{
    "use strict";

    var target = @getProxyInternalField(this, @proxyFieldTarget);
    var handler = @getProxyInternalField(this, @proxyFieldHandler);
    var propertyName = @toPropertyKey(propertyName);

    if (handler === null)
        @throwTypeError("Proxy has already been revoked. No more operations are allowed to be performed on it");

    var trap = handler.set;
    if (@isUndefinedOrNull(trap)) {
        @putByValWithThisSloppy(target, receiver, propertyName, value);
        return;
    }

    if (!@isCallable(trap))
        @throwTypeError("'set' property of a Proxy's handler should be callable");

    if (!trap.@call(handler, target, propertyName, value, @toThis(receiver)))
        return;

    if (@mustValidateResultOfProxyGetAndSetTraps(target))
        @handlePositiveProxySetTrapResult(target, propertyName, value);
})
(function (propertyName, receiver, value)
{
    "use strict";

    var target = @getProxyInternalField(this, @proxyFieldTarget);
    var handler = @getProxyInternalField(this, @proxyFieldHandler);
    var propertyName = @toPropertyKey(propertyName);

    if (handler === null)
        @throwTypeError("Proxy has already been revoked. No more operations are allowed to be performed on it");

    var trap = handler.set;
    if (@isUndefinedOrNull(trap)) {
        @putByValWithThisStrict(target, receiver, propertyName, value);
        return;
    }

    if (!@isCallable(trap))
        @throwTypeError("'set' property of a Proxy's handler should be callable");

    if (!trap.@call(handler, target, propertyName, value, @toThis(receiver)))
        @throwTypeError("Proxy object's 'set' trap returned falsy value for property '" + @String(propertyName) + "'");

    if (@mustValidateResultOfProxyGetAndSetTraps(target))
        @handlePositiveProxySetTrapResult(target, propertyName, value);
})
(function (propertyName, receiver, value)
{
    "use strict";

    var target = @getProxyInternalField(this, @proxyFieldTarget);
    var handler = @getProxyInternalField(this, @proxyFieldHandler);

    if (handler === null)
        @throwTypeError("Proxy has already been revoked. No more operations are allowed to be performed on it");

    var trap = handler.set;
    if (@isUndefinedOrNull(trap)) {
        @putByValWithThisSloppy(target, receiver, propertyName, value);
        return;
    }

    if (!@isCallable(trap))
        @throwTypeError("'set' property of a Proxy's handler should be callable");

    if (!trap.@call(handler, target, propertyName, value, @toThis(receiver)))
        return;

    if (@mustValidateResultOfProxyGetAndSetTraps(target))
        @handlePositiveProxySetTrapResult(target, propertyName, value);
})
(function (propertyName, receiver, value)
{
    "use strict";

    var target = @getProxyInternalField(this, @proxyFieldTarget);
    var handler = @getProxyInternalField(this, @proxyFieldHandler);

    if (handler === null)
        @throwTypeError("Proxy has already been revoked. No more operations are allowed to be performed on it");

    var trap = handler.set;
    if (@isUndefinedOrNull(trap)) {
        @putByValWithThisStrict(target, receiver, propertyName, value);
        return;
    }

    if (!@isCallable(trap))
        @throwTypeError("'set' property of a Proxy's handler should be callable");

    if (!trap.@call(handler, target, propertyName, value, @toThis(receiver)))
        @throwTypeError("Proxy object's 'set' trap returned falsy value for property '" + @String(propertyName) + "'");

    if (@mustValidateResultOfProxyGetAndSetTraps(target))
        @handlePositiveProxySetTrapResult(target, propertyName, value);
})
(function (context, index)
{
    "use strict";

    @assert(@isPromiseAllContext(context));

    var alreadyCalled = false;
    return (argument) => {
        if (alreadyCalled)
            return @undefined;
        alreadyCalled = true;

        var values = @getPromiseAllContextInternalField(context, @promiseAllContextFieldValues);
        @putByValDirect(values, index, argument);

        var remainingElementsCount = @getPromiseAllContextInternalField(context, @promiseAllContextFieldRemainingElementsCount);
        if (!--remainingElementsCount.value) {
            var promise = @getPromiseAllContextInternalField(context, @promiseAllContextFieldPromise);
            return @resolvePromiseWithFirstResolvingFunctionCallCheck(promise, values);
        }
    };
})
(function (argument, context)
{
    "use strict";

    @assert(@isPromiseAllContext(context));

    var promise = @getPromiseAllContextInternalField(context, @promiseAllContextFieldPromise);
    var values = @getPromiseAllContextInternalField(context, @promiseAllContextFieldValues);
    var remainingElementsCountObj = @getPromiseAllContextInternalField(context, @promiseAllContextFieldRemainingElementsCount);
    var index = @getPromiseAllContextInternalField(context, @promiseAllContextFieldIndex);

    @putByValDirect(values, index, argument);

    if (!--remainingElementsCountObj.value)
        return @resolvePromiseWithFirstResolvingFunctionCallCheck(promise, values);
})
(function (iterable)
{
    "use strict";

    if (!@isObject(this))
        @throwTypeError("|this| is not an object");

    var promiseCapability = @newPromiseCapability(this);
    var resolve = promiseCapability.resolve;
    var reject = promiseCapability.reject;
    var promise = promiseCapability.promise;

    var values = [];
    var index = 0;
    var remainingElementsCount = 1;

    try {
        var promiseResolve = this.resolve;
        if (!@isCallable(promiseResolve))
            @throwTypeError("Promise resolve is not a function");

        for (var value of iterable) {
            @putByValDirect(values, index, @undefined);
            var nextPromise = promiseResolve.@call(this, value);
            let currentIndex = index++;
            ++remainingElementsCount;
            nextPromise.then((argument) => {
                if (currentIndex < 0)
                    return @undefined;

                @putByValDirect(values, currentIndex, argument);
                currentIndex = -1;

                --remainingElementsCount;
                if (remainingElementsCount === 0)
                    return resolve.@call(@undefined, values);

                return @undefined;
            }, reject);
        }

        --remainingElementsCount;
        if (remainingElementsCount === 0)
            resolve.@call(@undefined, values);
    } catch (error) {
        reject.@call(@undefined, error);
    }

    return promise;
})
(function (argument)
{
    "use strict";

    return argument;
})
(function (argument)
{
    "use strict";

    throw argument;
})
(function (promise)
{
    "use strict";

    return function @reject(reason) {
        return @rejectPromiseWithFirstResolvingFunctionCallCheck(promise, reason);
    };
})
(function (argument, context)
{
    "use strict";

    @assert(@isPromiseAllContext(context));

    return @rejectPromiseWithFirstResolvingFunctionCallCheck(@getPromiseAllContextInternalField(context, @promiseAllContextFieldPromise), argument);
})
(function (promiseOrCapability, handler, argument, contextOrState)
{
    //
    //
    //
    //
    //
    //
    //
    //
    //
    "use strict";

    //

    if (@isUndefinedOrNull(handler)) {
        try {
            @assert(@isPromise(promiseOrCapability));
            if (contextOrState === @promiseStateFulfilled)
                @resolvePromise(promiseOrCapability, argument);
            else
                @rejectPromise(promiseOrCapability, argument);
        } catch {
            //
        }
        return;
    }

    //
    if (!promiseOrCapability) {
        @promiseReactionJobWithoutPromiseUnwrapAsyncContext(handler, argument, contextOrState);
        return;
    }

    var prev, hasAsyncContext = false;
    if (@isJSArray(contextOrState)) {
        prev = @getInternalField(@asyncContext, 0);
        hasAsyncContext = true;
        @putInternalField(@asyncContext, 0, contextOrState[1]);
        contextOrState = contextOrState[0];
    }

    //
    try {
        var result = (contextOrState) ? handler(argument, contextOrState) : handler(argument);
    } catch (error) {
        if (hasAsyncContext) {
            @putInternalField(@asyncContext, 0, prev);
        }

        if (@isPromise(promiseOrCapability)) {
            @rejectPromise(promiseOrCapability, error);
            return;
        }
        promiseOrCapability.reject.@call(@undefined, error);
        return;
    }

    if (@isPromise(promiseOrCapability)) {
        @resolvePromise(promiseOrCapability, result);
        if (hasAsyncContext) {
            @putInternalField(@asyncContext, 0, prev);
        }
        return;
    }
    promiseOrCapability.resolve.@call(@undefined, result);
    if (hasAsyncContext) {
        @putInternalField(@asyncContext, 0, prev);
    }
})
(function (handler, argument, context, asyncContext)
{
    "use strict";
    var prev, hasAsyncContext = false;
    if (asyncContext) {
        prev = @getInternalField(@asyncContext, 0);
        hasAsyncContext = true;
        @putInternalField(@asyncContext, 0, asyncContext);
    }

    try {
        if (context)
            handler(argument, context);
        else
            handler(argument);
    } catch {
        //
    }

    if (hasAsyncContext) {
        @putInternalField(@asyncContext, 0, prev);
    }
})
(function (handler, argument, context)
{
    "use strict";
    var prev, hasAsyncContext = false;
    if (@isJSArray(context)) {
        prev = @getInternalField(@asyncContext, 0);
        hasAsyncContext = true
        @putInternalField(@asyncContext, 0, context[1]);
        context = context[0];
    }

    try {
        if (context)
            handler(argument, context);
        else
            handler(argument);
    } catch {
        //
    }

    if (hasAsyncContext) {
        @putInternalField(@asyncContext, 0, prev);
    }
})
(function (constructor, reason)
{
    "use strict";

    @assert(constructor !== @Promise);
    var promiseCapability = @newPromiseCapabilitySlow(constructor);
    promiseCapability.reject.@call(@undefined, reason);
    return promiseCapability.promise;
})
(function (constructor, value)
{
    "use strict";

    if (@isPromise(value) && value.constructor === constructor)
        return value;

    if (constructor === @Promise) {
        var promise = @newPromise();
        @resolvePromiseWithFirstResolvingFunctionCallCheck(promise, value);
        return promise;
    }

    return @promiseResolveSlow(constructor, value);
})
(function (constructor, value)
{
    "use strict";

    @assert(constructor !== @Promise);
    var promiseCapability = @newPromiseCapabilitySlow(constructor);
    promiseCapability.resolve.@call(@undefined, value);
    return promiseCapability.promise;
})
(function (thenable, then, resolvingFunctions)
{
    "use strict";

    try {
        return then.@call(thenable, resolvingFunctions.resolve, resolvingFunctions.reject);
    } catch (error) {
        return resolvingFunctions.reject.@call(@undefined, error);
    }
})
(function (thenable, promiseToResolve)
{
    "use strict";

    @assert(@isPromise(thenable));
    @assert(@isPromise(promiseToResolve));

    //
    //
    var constructor = @speciesConstructor(thenable, @Promise);
    if (constructor !== @Promise && constructor !== @InternalPromise) {
        var asyncContext = @getInternalField(@asyncContext, 0);
        if (!asyncContext) {
            @promiseResolveThenableJobWithDerivedPromise(thenable, constructor, @createResolvingFunctions(promiseToResolve));
        } else {
            @promiseResolveThenableJobWithDerivedPromiseWithAsyncContext(thenable, constructor, @createResolvingFunctions(promiseToResolve), asyncContext);
        }
        
        return;
    }

    var flags = @getPromiseInternalField(thenable, @promiseFieldFlags);
    var state = flags & @promiseStateMask;
    var reactionsOrResult = @getPromiseInternalField(thenable, @promiseFieldReactionsOrResult);
    if (state === @promiseStatePending)
        @pushNewPromiseReaction(thenable, reactionsOrResult, promiseToResolve, @undefined, @undefined);
    else {
        if (state === @promiseStateRejected && !(flags & @promiseFlagsIsHandled))
            @hostPromiseRejectionTracker(thenable, @promiseRejectionHandle);
        @enqueueJob(@promiseReactionJob, promiseToResolve, @undefined, reactionsOrResult, state);
    }
    @putPromiseInternalField(thenable, @promiseFieldFlags, @getPromiseInternalField(thenable, @promiseFieldFlags) | @promiseFlagsIsHandled);
})
(function (thenable, then, resolvingFunctions, asyncContext)
{
    "use strict";
    var prev = @getInternalField(@asyncContext, 0);
    @putInternalField(@asyncContext, 0, asyncContext);

    try {
        const result = then.@call(thenable, resolvingFunctions.resolve, resolvingFunctions.reject);
        @putInternalField(@asyncContext, 0, prev);
        return result;
    } catch (error) {
        @putInternalField(@asyncContext, 0, prev);
        return resolvingFunctions.reject.@call(@undefined, error);
    }
})
(function (thenable, constructor, resolvingFunctions)
{
    "use strict";

    try {
        var promiseOrCapability = @newPromiseCapabilitySlow(constructor);
        @performPromiseThen(thenable, resolvingFunctions.resolve, resolvingFunctions.reject, promiseOrCapability, @undefined);
        return promiseOrCapability.promise;
    } catch (error) {
        return resolvingFunctions.reject.@call(@undefined, error);
    }
})
(function (thenable, constructor, resolvingFunctions, asyncContext)
{
    "use strict";
    var prev = @getInternalField(@asyncContext, 0);
    @putInternalField(@asyncContext, 0, asyncContext);

    try {
        var promiseOrCapability = @newPromiseCapabilitySlow(constructor);
        @performPromiseThen(thenable, resolvingFunctions.resolve, resolvingFunctions.reject, promiseOrCapability, @undefined);
        @putInternalField(@asyncContext, 0, prev);
        return promiseOrCapability.promise;
    } catch (error) {
        @putInternalField(@asyncContext, 0, prev);
        return resolvingFunctions.reject.@call(@undefined, error);
    }
})
(function (thenable, onFulfilled, onRejected, context)
{
    "use strict";

    @assert(@isPromise(thenable));

    //
    //
    var constructor = @speciesConstructor(thenable, @Promise);
    if (constructor !== @Promise && constructor !== @InternalPromise) {
        var asyncContext = @getInternalField(@asyncContext, 0);
        if (!asyncContext) {
            @promiseResolveThenableJobWithDerivedPromise(thenable, constructor, @createResolvingFunctionsWithoutPromise(onFulfilled, onRejected, context));
        } else {
            @promiseResolveThenableJobWithDerivedPromiseWithAsyncContext(thenable, constructor, @createResolvingFunctionsWithoutPromise(onFulfilled, onRejected, context), asyncContext);
        }
        return;
    }

    var flags = @getPromiseInternalField(thenable, @promiseFieldFlags);
    var state = flags & @promiseStateMask;
    var reactionsOrResult = @getPromiseInternalField(thenable, @promiseFieldReactionsOrResult);
    if (state === @promiseStatePending)
        @pushNewPromiseReaction(thenable, reactionsOrResult, @undefined, onFulfilled, onRejected, context);
    else {
        if (state === @promiseStateRejected) {
            if (!(flags & @promiseFlagsIsHandled))
                @hostPromiseRejectionTracker(thenable, @promiseRejectionHandle);
            @rejectWithoutPromise(reactionsOrResult, onFulfilled, onRejected, context);
        } else
            @fulfillWithoutPromise(reactionsOrResult, onFulfilled, onRejected, context);
    }
    @putPromiseInternalField(thenable, @promiseFieldFlags, @getPromiseInternalField(thenable, @promiseFieldFlags) | @promiseFlagsIsHandled);
})
(function (key, value)
{
    "use strict";

    var entry = this.ensureRegistered(key);

    if (entry.state > @ModuleFetch)
        @throwTypeError("Requested module is already fetched.");
    @fulfillFetch(entry, value);
})
(function (thenable, existingReactions, promiseOrCapability, onFulfilled, onRejected, context)
{
    "use strict";
    var asyncContext = @getInternalField(@asyncContext, 0);
    if (!existingReactions) {
        existingReactions = {
            @promiseOrCapability: promiseOrCapability,
            @onFulfilled: onFulfilled,
            @onRejected: onRejected,
            @context: asyncContext ? [context, asyncContext] : context,
            //
            @outOfLineReactionCounts: 0,
        };
        @putPromiseInternalField(thenable, @promiseFieldReactionsOrResult, existingReactions);
    } else {
        var outOfLineReactionCounts = existingReactions.@outOfLineReactionCounts;
        @putByValDirect(existingReactions, outOfLineReactionCounts++, promiseOrCapability);
        @putByValDirect(existingReactions, outOfLineReactionCounts++, onFulfilled);
        @putByValDirect(existingReactions, outOfLineReactionCounts++, onRejected);
        @putByValDirect(existingReactions, outOfLineReactionCounts++, asyncContext ? [context, asyncContext] : context);
        existingReactions.@outOfLineReactionCounts = outOfLineReactionCounts;
    }
})
(function (iterable)
{
    "use strict";

    if (!@isObject(this))
        @throwTypeError("|this| is not an object");

    var promiseCapability = @newPromiseCapability(this);
    var resolve = promiseCapability.resolve;
    var reject = promiseCapability.reject;
    var promise = promiseCapability.promise;

    try {
        var promiseResolve = this.resolve;
        if (!@isCallable(promiseResolve))
            @throwTypeError("Promise resolve is not a function");

        for (var value of iterable) {
            var nextPromise = promiseResolve.@call(this, value);
            nextPromise.then(resolve, reject);
        }
    } catch (error) {
        reject.@call(@undefined, error);
    }

    return promise;
})
(function (template)
{
    "use strict";

    var cookedSegments = @toObject(template, "String.raw requires template not be null or undefined");

    var rawSegments = @toObject(cookedSegments.raw, "String.raw requires template.raw not be null or undefined");

    var numberOfSubstitutions = @argumentCount() - 1;

    var segmentCount = @toLength(rawSegments.length);

    if (segmentCount <= 0)
        return '';

    var stringElements = '';
    for (var i = 0; ; ++i) {
        var segment = @toString(rawSegments[i]);
        stringElements += segment;

        if ((i + 1) === segmentCount)
            return stringElements;

        if (i < numberOfSubstitutions) {
            var substitutionIndexInArguments = i + 1;
            var next = @toString(arguments[substitutionIndexInArguments]);
            stringElements += next;
        }
    }
})
(function (callback )
{
    "use strict";

    var array = @toObject(this, "Array.prototype.reduce requires that |this| not be null or undefined");
    var length = @toLength(array.length);

    if (!@isCallable(callback))
        @throwTypeError("Array.prototype.reduce callback must be a function");

    var argumentCount = @argumentCount();
    if (length === 0 && argumentCount < 2)
        @throwTypeError("reduce of empty array with no initial value");

    var accumulator, k = 0;
    if (argumentCount > 1)
        accumulator = @argument(1);
    else {
        while (k < length && !(k in array))
            k += 1;
        if (k >= length)
            @throwTypeError("reduce of empty array with no initial value");
        accumulator = array[k++];
    }

    while (k < length) {
        if (k in array)
            accumulator = callback.@call(@undefined, accumulator, array[k], k, array);
        k += 1;
    }
    return accumulator;
})
(function (reducer )
{
    "use strict";

    if (!@isObject(this))
        @throwTypeError("Iterator.prototype.reduce requires that |this| be an Object.");

    if (!@isCallable(reducer)) {
        try {
            @iteratorGenericClose(this);
        } finally {
            @throwTypeError("Iterator.prototype.reduce reducer argument must be a function.");
        }
    }

    var iterated = this;
    var iteratedNextMethod = this.next;

    var accumulator;
    var counter = 0;
    if (@argumentCount() <= 1) {
        var result = @iteratorGenericNext(iteratedNextMethod, iterated);
        if (result.done)
            @throwTypeError("Iterator.prototype.reduce requires an initial value or an iterator that is not done.");
        accumulator = result.value;
        counter = 1;
    } else
        accumulator = @argument(1);

    for (;;) {
        var result = @iteratorGenericNext(iteratedNextMethod, iterated);
        if (result.done)
            break;

        var value = result.value;
        @ifAbruptCloseIterator(iterated, (
            accumulator = reducer(accumulator, value, counter++)
        ));
    }

    return accumulator;
})
(function (callback )
{
    //
    "use strict";

    var length = @typedArrayLength(this);

    if (!@isCallable(callback))
        @throwTypeError("TypedArray.prototype.reduce callback must be a function");

    var argumentCount = @argumentCount();
    if (length === 0 && argumentCount < 2)
        @throwTypeError("TypedArray.prototype.reduce of empty array with no initial value");

    var accumulator, k = 0;
    if (argumentCount > 1)
        accumulator = @argument(1);
    else
        accumulator = this[k++];

    for (; k < length; k++)
        accumulator = callback.@call(@undefined, accumulator, this[k], k, this);

    return accumulator;
})
(function (callback )
{
    "use strict";

    var array = @toObject(this, "Array.prototype.reduceRight requires that |this| not be null or undefined");
    var length = @toLength(array.length);

    if (!@isCallable(callback))
        @throwTypeError("Array.prototype.reduceRight callback must be a function");

    var argumentCount = @argumentCount();
    if (length === 0 && argumentCount < 2)
        @throwTypeError("reduceRight of empty array with no initial value");

    var accumulator, k = length - 1;
    if (argumentCount > 1)
        accumulator = @argument(1);
    else {
        while (k >= 0 && !(k in array))
            k -= 1;
        if (k < 0)
            @throwTypeError("reduceRight of empty array with no initial value");
        accumulator = array[k--];
    }

    while (k >= 0) {
        if (k in array)
            accumulator = callback.@call(@undefined, accumulator, array[k], k, array);
        k -= 1;
    }
    return accumulator;
})
(function (callback )
{
    //
    "use strict";

    var length = @typedArrayLength(this);

    if (!@isCallable(callback))
        @throwTypeError("TypedArray.prototype.reduceRight callback must be a function");

    var argumentCount = @argumentCount();
    if (length === 0 && argumentCount < 2)
        @throwTypeError("TypedArray.prototype.reduceRight of empty array with no initial value");

    var accumulator, k = length - 1;
    if (argumentCount > 1)
        accumulator = @argument(1);
    else
        accumulator = this[k--];

    for (; k >= 0; k--)
        accumulator = callback.@call(@undefined, accumulator, this[k], k, this);

    return accumulator;
})
(function (regexp, str)
{
    "use strict";

    var exec = regexp.exec;
    var builtinExec = @regExpBuiltinExec;
    if (exec !== builtinExec && @isCallable(exec)) {
        var result = exec.@call(regexp, str);
        if (result !== null && !@isObject(result))
            @throwTypeError("The result of a RegExp exec must be null or an object");
        return result;
    }
    return builtinExec.@call(regexp, str);
})
(function (reason)
{
    "use strict";

    if (!@isObject(this))
        @throwTypeError("|this| is not an object");

    if (this === @Promise) {
        var promise = @newPromise();
        @rejectPromiseWithFirstResolvingFunctionCallCheck(promise, reason);
        return promise;
    }

    return @promiseRejectSlow(this, reason);
})
(function (promise, reason)
{
    "use strict";

    @assert(@isPromise(promise));
    @assert((@getPromiseInternalField(promise, @promiseFieldFlags) & @promiseStateMask) == @promiseStatePending);

    var flags = @getPromiseInternalField(promise, @promiseFieldFlags);
    var reactions = @getPromiseInternalField(promise, @promiseFieldReactionsOrResult);
    @putPromiseInternalField(promise, @promiseFieldReactionsOrResult, reason);
    @putPromiseInternalField(promise, @promiseFieldFlags, flags | @promiseStateRejected);

    if (!(flags & @promiseFlagsIsHandled))
        @hostPromiseRejectionTracker(promise, @promiseRejectionReject);

    @triggerPromiseReactions(@promiseStateRejected, reactions, reason);
})
(function (promise, reason)
{
    "use strict";

    @assert(@isPromise(promise));
    var flags = @getPromiseInternalField(promise, @promiseFieldFlags);
    if (flags & @promiseFlagsIsFirstResolvingFunctionCalled)
        return;
    @putPromiseInternalField(promise, @promiseFieldFlags, flags | @promiseFlagsIsFirstResolvingFunctionCalled);
    return @rejectPromise(promise, reason);
})
(function (reason, onFulfilled, onRejected, context)
{
    "use strict";

    @enqueueJob(@promiseReactionJobWithoutPromise, onRejected, reason, context, @getInternalField(@asyncContext, 0));
})
(function (count)
{
    "use strict";

    if (@isUndefinedOrNull(this))
        @throwTypeError("String.prototype.repeat requires that |this| not be null or undefined");

    var string = @toString(this);
    count = @toIntegerOrInfinity(count);

    if (count < 0 || count === @Infinity)
        @throwRangeError("String.prototype.repeat argument must be greater than or equal to 0 and not be Infinity");

    if (string.length === 1)
        return @repeatCharacter(string, count);

    return @repeatSlowPath(string, count);
})
(function (string, count)
{
    "use strict";
    var repeatCount = (count / string.length) | 0;
    var remainingCharacters = count - repeatCount * string.length;
    var result = "";
    var operand = string;
    //
    //
    while (true) {
        if (repeatCount & 1)
            result += operand;
        repeatCount >>= 1;
        if (!repeatCount)
            break;
        operand += operand;
    }
    if (remainingCharacters)
        result += @stringSubstring.@call(string, 0, remainingCharacters);
    return result;
})
(function (string, count)
{
    "use strict";

    //
    if (count === 0 || string.length === 0)
        return "";

    //
    if (count === 1)
        return string;

    if (string.length * count > @MAX_STRING_LENGTH)
        @throwOutOfMemoryError();

    //
    //
    var result = "";
    var operand = string;
    while (true) {
        if (count & 1)
            result += operand;
        count >>= 1;
        if (!count)
            return result;
        operand += operand;
    }
})
(function (strArg, replace)
{
    "use strict";

    if (!@isObject(this))
        @throwTypeError("RegExp.prototype.@@replace requires that |this| be an Object");

    var regexp = this;

    var str = @toString(strArg);
    var stringLength = str.length;
    var functionalReplace = @isCallable(replace);

    if (!functionalReplace)
        replace = @toString(replace);

    var flags = @toString(regexp.flags);
    var global = @stringIncludesInternal.@call(flags, "g");
    var unicode = false;

    if (global) {
        unicode = @stringIncludesInternal.@call(flags, "u") || @stringIncludesInternal.@call(flags, "v");
        regexp.lastIndex = 0;
    }

    var resultList = [];
    var result;
    var done = false;
    while (!done) {
        result = @regExpExec(regexp, str);

        if (result === null)
            done = true;
        else {
            @arrayPush(resultList, result);
            if (!global)
                done = true;
            else {
                var matchStr = @toString(result[0]);

                if (!matchStr.length) {
                    var thisIndex = @toLength(regexp.lastIndex);
                    regexp.lastIndex = @advanceStringIndex(str, thisIndex, unicode);
                }
            }
        }
    }

    var accumulatedResult = "";
    var nextSourcePosition = 0;

    for (var i = 0, resultListLength = resultList.length; i < resultListLength; ++i) {
        var result = resultList[i];
        var nCaptures = result.length - 1;
        if (nCaptures < 0)
            nCaptures = 0;
        var matched = @toString(result[0]);
        var matchLength = matched.length;
        var position = @toIntegerOrInfinity(result.index);
        position = (position > stringLength) ? stringLength : position;
        position = (position < 0) ? 0 : position;

        var captures = [];
        for (var n = 1; n <= nCaptures; n++) {
            var capN = result[n];
            if (capN !== @undefined)
                capN = @toString(capN);
            @arrayPush(captures, capN);
        }

        var replacement;
        var namedCaptures = result.groups;

        if (functionalReplace) {
            var replacerArgs = [ matched ];
            for (var j = 0; j < captures.length; j++)
                @arrayPush(replacerArgs, captures[j]);

            @arrayPush(replacerArgs, position);
            @arrayPush(replacerArgs, str);

            if (namedCaptures !== @undefined)
                @arrayPush(replacerArgs, namedCaptures);

            var replValue = replace.@apply(@undefined, replacerArgs);
            replacement = @toString(replValue);
        } else {
            if (namedCaptures !== @undefined)
                namedCaptures = @toObject(namedCaptures, "RegExp.prototype[Symbol.replace] requires 'groups' property of a match not be null");

            replacement = @getSubstitution(matched, str, position, captures, namedCaptures, replace);
        }

        if (position >= nextSourcePosition) {
            accumulatedResult = accumulatedResult + @stringSubstring.@call(str, nextSourcePosition, position) + replacement;
            nextSourcePosition = position + matchLength;
        }
    }

    if (nextSourcePosition >= stringLength)
        return  accumulatedResult;

    return accumulatedResult + @stringSubstring.@call(str, nextSourcePosition);
})
(function (search, replace)
{
    "use strict";

    if (@isUndefinedOrNull(this))
        @throwTypeError("String.prototype.replace requires that |this| not be null or undefined");

    if (@isObject(search)) {
        var replacer = search.@@replace;
        if (!@isUndefinedOrNull(replacer)) {
            if (!@hasObservableSideEffectsForStringReplace(search, replacer))
                return @toString(this).@replaceUsingRegExp(search, replace);
            return replacer.@call(search, this, replace);
        }
    }

    var thisString = @toString(this);
    var searchString = @toString(search);
    return thisString.@replaceUsingStringSearch(searchString, replace);
})
(function (search, replace)
{
    "use strict";

    if (@isUndefinedOrNull(this))
        @throwTypeError("String.prototype.replaceAll requires |this| not to be null nor undefined");

    if (@isObject(search)) {
        if (@isRegExp(search) && !@stringIncludesInternal.@call(@toString(search.flags), "g"))
            @throwTypeError("String.prototype.replaceAll argument must not be a non-global regular expression");

        var replacer = search.@@replace;
        if (!@isUndefinedOrNull(replacer)) {
            if (!@hasObservableSideEffectsForStringReplace(search, replacer))
                return @toString(this).@replaceUsingRegExp(search, replace);
            return replacer.@call(search, this, replace);
        }
    }

    var thisString = @toString(this);
    var searchString = @toString(search);
    return thisString.@replaceAllUsingStringSearch(searchString, replace);
})
(function (entry, parameters, fetcher)
{
    //

    "use strict";

    if (entry.fetch) {
        var promiseConstructor = @InternalPromise;
        var newPromise = @createPromise(promiseConstructor,  true);
        entry.fetch.then(
            (result) => @fulfillPromiseWithFirstResolvingFunctionCallCheck(newPromise, result),
            (error) => @rejectPromiseWithFirstResolvingFunctionCallCheck(newPromise, this.createTypeErrorCopy(error)));
        return newPromise;
    }

    //
    //
    //
    //
    //
    //
    var fetchPromise = this.fetch(entry.key, parameters, fetcher).then((source) => {
        @setStateToMax(entry, @ModuleInstantiate);
        return source;
    });
    entry.fetch = fetchPromise;
    return fetchPromise;
})
(async function (moduleName, referrer, parameters, fetcher)
{
    "use strict";

    var key = moduleName;
    var entry = this.ensureRegistered(key);
    var mod;
    if (entry.evaluated && (mod = entry.module)) {
        return this.getModuleNamespaceObject(mod);
    }  
    entry = await this.requestSatisfy(entry, parameters, fetcher, new @Set);
    if (entry.evaluated && (mod = entry.module)) {
        return this.getModuleNamespaceObject(mod);
    }
    await this.linkAndEvaluateModule(entry.key, fetcher);
    return this.getModuleNamespaceObject(entry.module);
})
(function (entry, parameters, fetcher)
{
    //

    "use strict";

    //
    if (entry.instantiate)
        return entry.instantiate;

    var instantiatePromise = (async () => {
        var sourcePossiblyPromise = this.requestFetch(entry, parameters, fetcher);
        var source;

        //
        if (@isPromise(sourcePossiblyPromise)) {
            const state =
              @getPromiseInternalField(sourcePossiblyPromise, @promiseFieldFlags) &
              @promiseStateMask;
            if (state === @promiseStateFulfilled) {
              source = @getPromiseInternalField(
                sourcePossiblyPromise,
                @promiseFieldReactionsOrResult
              );
            } else if (state === @promiseStateRejected) {
              @putPromiseInternalField(
                sourcePossiblyPromise,
                @promiseFieldFlags,
                @getPromiseInternalField(sourcePossiblyPromise, @promiseFieldFlags) |
                  @promiseFlagsIsHandled
              );
              throw @getPromiseInternalField(
                sourcePossiblyPromise,
                @promiseFieldReactionsOrResult
              );
            } else {
              source = await sourcePossiblyPromise;
            }
          } else {
            source = sourcePossiblyPromise;
          }          
            

        //
        //
        //
        if (entry.instantiate)
            return await entry.instantiate;
        entry.instantiate = instantiatePromise;

        var key = entry.key;
        var parseModuleRequest = this.parseModule(key, source);
        var moduleRecord;

        //
        if (@isPromise(parseModuleRequest)) {
            const state =
              @getPromiseInternalField(parseModuleRequest, @promiseFieldFlags) &
              @promiseStateMask;
            if (state === @promiseStateFulfilled) {
              moduleRecord = @getPromiseInternalField(
                parseModuleRequest,
                @promiseFieldReactionsOrResult
              );
            } else if (state === @promiseStateRejected) {
              @putPromiseInternalField(
                parseModuleRequest,
                @promiseFieldFlags,
                @getPromiseInternalField(parseModuleRequest, @promiseFieldFlags) |
                  @promiseFlagsIsHandled
              );
              throw @getPromiseInternalField(
                parseModuleRequest,
                @promiseFieldReactionsOrResult
              );
            } else {
              moduleRecord = await parseModuleRequest;
            }
          } else {
            moduleRecord = parseModuleRequest;
          } 
          
        var dependenciesMap = moduleRecord.dependenciesMap;
        var requestedModules = this.requestedModules(moduleRecord);
        var dependencies = @newArrayWithSize(requestedModules.length);
        for (var i = 0, length = requestedModules.length; i < length; ++i) {
            var depName = requestedModules[i];
            var depKey = this.resolve(depName, key, fetcher);
            var depEntry = this.ensureRegistered(depKey);
            @putByValDirect(dependencies, i, depEntry);
            dependenciesMap.@set(depName, depEntry);
        }
        entry.dependencies = dependencies;
        entry.module = moduleRecord;
        @setStateToMax(entry, @ModuleSatisfy);
        return entry;
    })();
    return instantiatePromise;
})
(function (entry, parameters, fetcher, visited)
{
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //

    "use strict";
    
    var satisfyingEntries = new @Set;
    return this.requestSatisfyUtil(entry, parameters, fetcher, visited, satisfyingEntries).then((entry) => {
        satisfyingEntries.@forEach((satisfyingEntry) => {
            @cacheSatisfy(satisfyingEntry);
            satisfyingEntry.isSatisfied = true;
        });
        return entry;
    });
})
(function (entry, parameters, fetcher, visited, satisfyingEntries)
{
    //

    "use strict";

    if (entry.satisfy)
        return entry.satisfy;

    visited.@add(entry);
    var satisfyPromise = this.requestInstantiate(entry, parameters, fetcher).then((entry) => {
        if (entry.satisfy)
            return entry.satisfy;

        var depLoads = this.requestedModuleParameters(entry.module);
        for (var i = 0, length = entry.dependencies.length; i < length; ++i) {
            var parameters = depLoads[i];
            var depEntry = entry.dependencies[i];
            var promise;

            //
            //
            //
            //
            //
            //
            //
            //
            //
            if (visited.@has(depEntry))
                promise = this.requestInstantiate(depEntry, parameters, fetcher);
            else {
                //
                promise = this.requestSatisfyUtil(depEntry, parameters, fetcher, visited, satisfyingEntries);
            }
            @putByValDirect(depLoads, i, promise);
        }

        //
        //
        //
        //
        //
        //
        //
        //
        //
        //
        //
        //
        //
        //
        //
        //
        //
        //
        //
        //
        //
        //
        //
        //
        //
        //
        //
        //
        //
        //
        //
        //
        //
        //
        return @InternalPromise.internalAll(depLoads).then((depEntries) => {
            if (entry.satisfy)
                return entry;
            return @cacheSatisfyAndReturn(entry, depEntries, satisfyingEntries);
        });
    });

    return satisfyPromise;
})
(function (value)
{
    "use strict";

    if (!@isObject(this))
        @throwTypeError("|this| is not an object");

    return @promiseResolve(this, value);
})
(function (promise, resolution)
{
    "use strict";

    @assert(@isPromise(promise));

    if (resolution === promise)
        return @rejectPromise(promise, @makeTypeError("Cannot resolve a promise with itself"));

    if (!@isObject(resolution))
        return @fulfillPromise(promise, resolution);

    var then;
    try {
        then = resolution.then;
    } catch (error) {
        return @rejectPromise(promise, error);
    }

    if (@isPromise(resolution) && then === @defaultPromiseThen) {
        @enqueueJob(@promiseResolveThenableJobFast, resolution, promise);
        return;
    }

    if (!@isCallable(then))
        return @fulfillPromise(promise, resolution);

    var asyncContext = @getInternalField(@asyncContext, 0);
    if (!asyncContext) {
        @enqueueJob(@promiseResolveThenableJob, resolution, then, @createResolvingFunctions(promise), @undefined);
    } else {
        @enqueueJob(@promiseResolveThenableJobWithAsyncContext, resolution, then, @createResolvingFunctions(promise), asyncContext);
    }
})
(function (promise, value)
{
    "use strict";

    @assert(@isPromise(promise));
    var flags = @getPromiseInternalField(promise, @promiseFieldFlags);
    if (flags & @promiseFlagsIsFirstResolvingFunctionCalled)
        return;
    @putPromiseInternalField(promise, @promiseFieldFlags, flags | @promiseFlagsIsFirstResolvingFunctionCalled);
    return @resolvePromise(promise, value);
})
(function (resolution, onFulfilled, onRejected, context, temp)
{
    "use strict";

    if (!@isObject(resolution)) {
        @fulfillWithoutPromise(resolution, onFulfilled, onRejected, context);
        return;
    }

    var then;
    try {
        then = resolution.then;
    } catch (error) {
        @rejectWithoutPromise(error, onFulfilled, onRejected, context);
        return;
    }

    if (@isPromise(resolution) && then === @defaultPromiseThen) {
        @enqueueJob(@promiseResolveThenableJobWithoutPromiseFast, resolution, onFulfilled, onRejected, context);
        return;
    }

    if (!@isCallable(then)) {
        @fulfillWithoutPromise(resolution, onFulfilled, onRejected, context);
        return;
    }

    //
    var asyncContext = @getInternalField(@asyncContext, 0);
    if (!asyncContext) {
        @enqueueJob(@promiseResolveThenableJob, resolution, then, @createResolvingFunctionsWithoutPromise(onFulfilled, onRejected, context));
    } else {
        @enqueueJob(@promiseResolveThenableJobWithAsyncContext, resolution, then, @createResolvingFunctionsWithoutPromise(onFulfilled, onRejected, context), asyncContext);
    }
})
(function (resolution, onFulfilled, onRejected, context)
{
    "use strict";

    if (@isPromise(resolution)) {
        try {
            var { constructor } = resolution;
        } catch (error) {
            onRejected(error, context);
            return;
        }

        if (constructor === @Promise || constructor === @InternalPromise)
            return @performPromiseThen(resolution, onFulfilled, onRejected, @undefined, context);
    }

    return @resolveWithoutPromise(resolution, onFulfilled, onRejected, context);
})
(function (value)
{
    "use strict";

    @assert(@isAsyncFromSyncIterator(this));

    var promise = @newPromise();

    if (!@isObject(this) || !@isObject(@getAsyncFromSyncIteratorInternalField(this, @asyncFromSyncIteratorFieldSyncIterator))) {
        @rejectPromiseWithFirstResolvingFunctionCallCheck(promise, @makeTypeError('Iterator is not an object.'));
        return promise;
    }

    var syncIterator = @getAsyncFromSyncIteratorInternalField(this, @asyncFromSyncIteratorFieldSyncIterator);

    var returnMethod;

    try {
        returnMethod = syncIterator.return;
    } catch (e) {
        @rejectPromiseWithFirstResolvingFunctionCallCheck(promise, e);
        return promise;
    }

    if (@isUndefinedOrNull(returnMethod)) {
        @resolvePromiseWithFirstResolvingFunctionCallCheck(promise, { value, done: true });
        return promise;
    }
    
    try {
        var returnResult = @argumentCount() === 0 ? returnMethod.@call(syncIterator) : returnMethod.@call(syncIterator, value);

        if (!@isObject(returnResult)) {
            @rejectPromiseWithFirstResolvingFunctionCallCheck(promise, @makeTypeError('Iterator result interface is not an object.'));
            return promise;
        }

        var onFulfilled = returnResult.done ? @asyncFromSyncIteratorOnFulfilledDone : @asyncFromSyncIteratorOnFulfilledContinue;
        @resolveWithoutPromiseForAsyncAwait(returnResult.value, onFulfilled, @asyncFromSyncIteratorOnRejected, { @promise: promise, @syncIterator: @undefined });
    } catch (e) {
        @rejectPromiseWithFirstResolvingFunctionCallCheck(promise, e);
    }

    return promise;
})
(function (value)
{
    "use strict";

    return @asyncGeneratorEnqueue(this, value, @GeneratorResumeModeReturn);
})
(function (value)
{
    "use strict";

    if (!@isGenerator(this))
        @throwTypeError("|this| should be a generator");

    var state = @getGeneratorInternalField(this, @generatorFieldState);
    if (state === @GeneratorStateCompleted)
        return { value, done: true };

    return @generatorResume(this, state, value, @GeneratorResumeModeReturn);
})
(function ()
{
    "use strict";

    if (!@isIteratorHelper(this))
        @throwTypeError("|this| should be an iterator helper");

    var generator = @getIteratorHelperInternalField(this, @iteratorHelperFieldGenerator);
    var state = @getGeneratorInternalField(generator, @generatorFieldState);
    if (state === @GeneratorStateInit) {
        @putGeneratorInternalField(generator, @generatorFieldState, @GeneratorStateCompleted);

        var underlyingIterator = @getIteratorHelperInternalField(this, @iteratorHelperFieldUnderlyingIterator);
        if (underlyingIterator !== null)
            @iteratorGenericClose(underlyingIterator);

        return { value: @undefined, done: true };
    }

    if (state === @GeneratorStateCompleted)
        return { value: @undefined, done: true };

    return @generatorResume(generator, state, @undefined, @GeneratorResumeModeReturn);
})
(function ()
{
    "use strict";

    //
    //
    //
    if (!@isWrapForValidIterator(this))
        @throwTypeError("%WrapForValidIteratorPrototype%.next requires that |this| be a WrapForValidIteratorPrototype object");

    //
    var iterator = @getWrapForValidIteratorInternalField(this, @wrapForValidIteratorFieldIteratedIterator);
    //
    @assert(@isObject(iterator));
    //
    var returnMethod = iterator.return;
    //
    //
    if (@isUndefinedOrNull(returnMethod))
        return { value: @undefined, done: true };
    //
    return returnMethod.@call(iterator);
})
(function (regexp)
{
    "use strict";

    if (@isUndefinedOrNull(this))
        @throwTypeError("String.prototype.search requires that |this| not be null or undefined");

    if (@isObject(regexp)) {
        var searcher = regexp.@@search;
        if (!@isUndefinedOrNull(searcher))
            return searcher.@call(regexp, this);
    }

    var thisString = @toString(this);
    var createdRegExp = @regExpCreate(regexp, @undefined);
    return createdRegExp.@@search(thisString);
})
(function (entry, newState)
{
    //

    "use strict";

    if (entry.state < newState)
        entry.state = newState;
})
(function ()
{
    "use strict";
    return @createHTML("String.prototype.small", this, "small", "", "");
})
(function (callback )
{
    "use strict";

    var array = @toObject(this, "Array.prototype.some requires that |this| not be null or undefined");
    var length = @toLength(array.length);

    if (!@isCallable(callback))
        @throwTypeError("Array.prototype.some callback must be a function");
    
    var thisArg = @argument(1);
    for (var i = 0; i < length; i++) {
        if (!(i in array))
            continue;
        if (callback.@call(thisArg, array[i], i, array))
            return true;
    }
    return false;
})
(function (predicate)
{
    "use strict";

    if (!@isObject(this))
        @throwTypeError("Iterator.prototype.some requires that |this| be an Object.");

    if (!@isCallable(predicate)) {
        try {
            @iteratorGenericClose(this);
        } finally {
            @throwTypeError("Iterator.prototype.some callback must be a function.");
        }
    }

    var iterated = this;
    var count = 0;
    var wrapper = { @@iterator: function () { return iterated; }};
    for (var item of wrapper) {
        if (predicate(item, count++))
            return true;
    }

    return false;
})
(function (obj, defaultConstructor)
{
    "use strict";

    var constructor = obj.constructor;
    if (constructor === @undefined)
        return defaultConstructor;
    if (!@isObject(constructor))
        @throwTypeError("|this|.constructor is not an Object or undefined");
    constructor = constructor.@@species;
    if (@isUndefinedOrNull(constructor))
        return defaultConstructor;
    if (@isConstructor(constructor))
        return constructor;
    @throwTypeError("|this|.constructor[Symbol.species] is not a constructor");
})
(function (string, limit)
{
    "use strict";

    //
    //
    if (!@isObject(this))
        @throwTypeError("RegExp.prototype.@@split requires that |this| be an Object");
    var regexp = this;

    //
    var str = @toString(string);

    //
    var speciesConstructor = @speciesConstructor(regexp, @RegExp);

    if (speciesConstructor === @RegExp && !@hasObservableSideEffectsForRegExpSplit(regexp))
        return @regExpSplitFast.@call(regexp, str, limit);

    //
    var flags = @toString(regexp.flags);

    //
    //
    var unicodeMatching = @stringIncludesInternal.@call(flags, "u") || @stringIncludesInternal.@call(flags, "v");
    //
    //
    var newFlags = @stringIncludesInternal.@call(flags, "y") ? flags : flags + "y";

    //
    var splitter = new speciesConstructor(regexp, newFlags);

    //
    //
    if (!@hasObservableSideEffectsForRegExpSplit(splitter))
        return @regExpSplitFast.@call(splitter, str, limit);

    //
    //
    var result = [];

    //
    limit = (limit === @undefined) ? 0xffffffff : limit >>> 0;

    //
    if (!limit)
        return result;

    //
    var size = str.length;

    //
    if (!size) {
        //
        var z = @regExpExec(splitter, str);
        //
        if (z !== null)
            return result;
        //
        @putByValDirect(result, 0, str);
        //
        return result;
    }

    //
    var position = 0;
    //
    var matchPosition = 0;

    //
    while (matchPosition < size) {
        //
        splitter.lastIndex = matchPosition;
        //
        var matches = @regExpExec(splitter, str);
        //
        if (matches === null)
            matchPosition = @advanceStringIndex(str, matchPosition, unicodeMatching);
        //
        else {
            //
            var endPosition = @toLength(splitter.lastIndex);
            //
            endPosition = (endPosition <= size) ? endPosition : size;
            //
            if (endPosition === position)
                matchPosition = @advanceStringIndex(str, matchPosition, unicodeMatching);
            //
            else {
                //
                var subStr = @stringSubstring.@call(str, position, matchPosition);
                //
                //
                @arrayPush(result, subStr);
                //
                if (result.length == limit)
                    return result;

                //
                position = endPosition;
                //
                //
                var numberOfCaptures = matches.length > 1 ? matches.length - 1 : 0;

                //
                var i = 1;
                //
                while (i <= numberOfCaptures) {
                    //
                    var nextCapture = matches[i];
                    //
                    //
                    @arrayPush(result, nextCapture);
                    //
                    if (result.length == limit)
                        return result;
                    //
                    i++;
                }
                //
                matchPosition = position;
            }
        }
    }
    //
    var remainingStr = @stringSubstring.@call(str, position, size);
    //
    @arrayPush(result, remainingStr);
    //
    return result;
})
(function (separator, limit)
{
    "use strict";
    
    if (@isUndefinedOrNull(this))
        @throwTypeError("String.prototype.split requires that |this| not be null or undefined");
    
    if (@isObject(separator)) {
        var splitter = separator.@@split;
        if (!@isUndefinedOrNull(splitter))
            return splitter.@call(separator, this, limit);
    }
    
    return @stringSplitFast.@call(this, separator, limit);
})
(function ()
{
    "use strict";
    return @createHTML("String.prototype.strike", this, "strike", "", "");
})
(function ()
{
    "use strict";

    var result = @toString(this);
    for (var i = 0, length = @argumentCount(); i < length; ++i)
        result += @toString(arguments[i]);
    return result;
})
(function ()
{
    "use strict";
    return @createHTML("String.prototype.sub", this, "sub", "", "");
})
(function ()
{
    "use strict";
    return @createHTML("String.prototype.sup", this, "sup", "", "");
})
(function (value)
{
    "use strict";

    if (!@isCallable(this))
        return false;

    if (@isBoundFunction(this))
        return @hasInstanceBoundFunction(this, value);

    var target = this.prototype;
    return @instanceOf(value, target);
})
(function (limit)
{
    "use strict";

    if (!@isObject(this))
        @throwTypeError("Iterator.prototype.take requires that |this| be an Object.");

    var numLimit;
    @ifAbruptCloseIterator(this, numLimit = @toNumber(limit));
    if (numLimit !== numLimit) {
        try {
            @iteratorGenericClose(this);
        } finally {
            @throwRangeError("Iterator.prototype.take argument must not be NaN.");
        }
    }

    var intLimit = @toIntegerOrInfinity(numLimit);
    if (intLimit < 0) {
        try {
            @iteratorGenericClose(this);
        } finally {
            @throwRangeError("Iterator.prototype.take argument must be non-negative.");
        }
    }

    var iterated = this;
    var iteratedNextMethod = iterated.next;

    var generator = (function*() {
        var remaining = intLimit;
        for (;;) {
            if (remaining === 0) {
                @iteratorGenericClose(iterated);
                return;
            }

            if (remaining !== @Infinity)
                remaining--;

            var result = @iteratorGenericNext(iteratedNextMethod, iterated);
            if (result.done)
                return;

            var value = result.value;
            @ifAbruptCloseIterator(iterated, (
                yield value
            ));
        }
    })();

    return @iteratorHelperCreate(generator, iterated);
})
(function (onFulfilled, onRejected)
{
    "use strict";

    if (!@isPromise(this))
        @throwTypeError("|this| is not a Promise");

    var constructor = @speciesConstructor(this, @Promise);

    var promise;
    var promiseOrCapability;
    if (constructor === @Promise) {
        promiseOrCapability = @newPromise();
        promise = promiseOrCapability;
    } else {
        promiseOrCapability = @newPromiseCapabilitySlow(constructor);
        promise = promiseOrCapability.promise;
    }

    @performPromiseThen(this, onFulfilled, onRejected, promiseOrCapability, @undefined);
    return promise;
})
(function (exception)
{
    "use strict";

    @assert(@isAsyncFromSyncIterator(this));

    var promise = @newPromise();

    if (!@isObject(this) || !@isObject(@getAsyncFromSyncIteratorInternalField(this, @asyncFromSyncIteratorFieldSyncIterator))) {
        @rejectPromiseWithFirstResolvingFunctionCallCheck(promise, @makeTypeError('Iterator is not an object.'));
        return promise;
    }

    var syncIterator = @getAsyncFromSyncIteratorInternalField(this, @asyncFromSyncIteratorFieldSyncIterator);

    var throwMethod;

    try {
        throwMethod = syncIterator.throw;
    } catch (e) {
        @rejectPromiseWithFirstResolvingFunctionCallCheck(promise, e);
        return promise;
    }

    if (@isUndefinedOrNull(throwMethod)) {
        var returnMethod;
        try {
            returnMethod = syncIterator.return;
        } catch (e) {
            @rejectPromiseWithFirstResolvingFunctionCallCheck(promise, e);
            return promise;
        }
        var returnResult = returnMethod.@call(syncIterator);
        if (!@isObject(returnResult)) {
            @rejectPromiseWithFirstResolvingFunctionCallCheck(promise, @makeTypeError('Iterator result interface is not an object.'));
            return promise;
        }
        @rejectPromiseWithFirstResolvingFunctionCallCheck(promise, @makeTypeError('Iterator does not provide a throw method.'));
        return promise;
    }
    
    try {
        var throwResult = @argumentCount() === 0 ? throwMethod.@call(syncIterator) : throwMethod.@call(syncIterator, exception);
        
        if (!@isObject(throwResult)) {
            @rejectPromiseWithFirstResolvingFunctionCallCheck(promise, @makeTypeError('Iterator result interface is not an object.'));
            return promise;
        }
        
        var onFulfilled = throwResult.done ? @asyncFromSyncIteratorOnFulfilledDone : @asyncFromSyncIteratorOnFulfilledContinue;
        @resolveWithoutPromiseForAsyncAwait(throwResult.value, onFulfilled, @asyncFromSyncIteratorOnRejected, { @promise: promise, @syncIterator: syncIterator });
    } catch (e) {
        @rejectPromiseWithFirstResolvingFunctionCallCheck(promise, e);
    }
    
    return promise;
})
(function (exception)
{
    "use strict";
    
    return @asyncGeneratorEnqueue(this, exception, @GeneratorResumeModeThrow);
})
(function (exception)
{
    "use strict";

    if (!@isGenerator(this))
        @throwTypeError("|this| should be a generator");

    var state = @getGeneratorInternalField(this, @generatorFieldState);
    if (state === @GeneratorStateCompleted)
        throw exception;

    return @generatorResume(this, state, exception, @GeneratorResumeModeThrow);
})
(function ()
{
    "use strict";

    var length = @typedArrayLength(this);

    if (length == 0)
        return "";

    var string = "";
    for (var i = 0; i < length; ++i) {
        if (i > 0)
            string += ",";
        var element = this[i];
        if (!@isUndefinedOrNull(element))
            string += @toString(element.toLocaleString(@argument(0), @argument(1)));
    }

    return string;
})
(function (state, reactions, argument)
{
    "use strict";

    if (!reactions)
        return;

    var isResolved = state === @promiseStateFulfilled;
    var handler = isResolved ? reactions.@onFulfilled : reactions.@onRejected;

    @enqueueJob(@promiseReactionJob, reactions.@promiseOrCapability, handler, argument, handler ? reactions.@context : state);

    for (var i = 0, count = reactions.@outOfLineReactionCounts; i < count; i += 4) {
        var promise = reactions[i];
        var handler = isResolved ? reactions[i + 1] : reactions[i + 2];
        var context = reactions[i + 3];
        @enqueueJob(@promiseReactionJob, promise, handler, argument, handler ? context : state);
    }
    @assert(i === count);
})
(function (callback )
{
    "use strict";

    if (!@isObject(this))
        @throwTypeError("|this| is not an object");

    var args = [];
    for (var i = 1; i < @argumentCount(); i++)
        @putByValDirect(args, i - 1, arguments[i]);

    var promiseCapability = @newPromiseCapability(this);
    try {
        var value = callback.@apply(@undefined, args);
        promiseCapability.resolve.@call(@undefined, value);
    } catch (error) {
        promiseCapability.reject.@call(@undefined, error);
    }

    return promiseCapability.promise;
})
(function (value)
{
    'use strict';

    if (!@isAsyncDisposableStack(this))
        @throwTypeError("AsyncDisposableStack.prototype.use requires that |this| be a AsyncDisposableStack object");

    if (@getAsyncDisposableStackInternalField(this, @asyncDisposableStackFieldState) === @AsyncDisposableStackStateDisposed)
        throw new @ReferenceError("AsyncDisposableStack.prototype.use requires that |this| be a pending AsyncDisposableStack object");

    @addDisposableResource(@getDisposableStackInternalField(this, @disposableStackFieldCapability), value,  true);

    return value;
})
(function (value)
{
    'use strict';

    if (!@isDisposableStack(this))
        @throwTypeError("DisposableStack.prototype.use requires that |this| be a DisposableStack object");

    if (@getDisposableStackInternalField(this, @disposableStackFieldState) === @DisposableStackStateDisposed)
        throw new @ReferenceError("DisposableStack.prototype.use requires that |this| be a pending DisposableStack object");

    @addDisposableResource(@getDisposableStackInternalField(this, @disposableStackFieldCapability), value,  false);

    return value;
})
(function (windowSize )
{
    "use strict";

    if (!@isObject(this))
        @throwTypeError("Iterator.prototype.windows requires that |this| be an Object.");

    var numWindowSize = @toNumber(windowSize);
    if (numWindowSize !== numWindowSize)
        @throwRangeError("Iterator.prototype.windows requires that first argument not be NaN.");

    var intWindowSize = @toIntegerOrInfinity(numWindowSize);
    if (intWindowSize < 1 || intWindowSize > @MAX_ARRAY_INDEX)
        @throwRangeError("Iterator.prototype.windows requires that first argument be between 1 and 2**32 - 1.");

    var undersized = @argument(1) ?? "only-full";
    if (undersized !== "only-full" && undersized !== "allow-partial")
        @throwTypeError("Iterator.prototype.windows requires that second argument be \"only-full\" or \"allow-partial\".");

    var iterated = this;
    var iteratedNextMethod = this.next;

    var generator = (function*() {
        var buffer = [];

        for (;;) {
            var result = @iteratorGenericNext(iteratedNextMethod, iterated);
            if (result.done) {
                if (undersized === "allow-partial" && buffer.length && buffer.length < intWindowSize)
                    yield buffer;
                return;
            }

            if (buffer.length === intWindowSize) {
                for (var i = 0; i < buffer.length - 1; ++i)
                    buffer[i] = buffer[i + 1];
                buffer[buffer.length - 1] = result.value;
            } else
                @arrayPush(buffer, result.value);

            if (buffer.length === intWindowSize) {
                var copy = @newArrayWithSize(buffer.length);
                for (var i = 0; i < buffer.length; ++i)
                    copy[i] = buffer[i];

                @ifAbruptCloseIterator(iterated, (
                    yield copy
                ));
            }
        }
    })();

    return @iteratorHelperCreate(generator, iterated);
})
(function ()
{
    "use strict";

    return @newPromiseCapability(this);
})
(function (fromShadowRealm, shadowRealm, target)
{
    "use strict";

    if (@isCallable(target))
        return @createRemoteFunction(target, fromShadowRealm ? null : shadowRealm);

    if (@isObject(target))
        @throwTypeError("value passing between realms must be callable or primitive");

    return target;
})
(function (iterator)
{
    var wrapper = @Object.@create(null);
    wrapper.@@iterator = function() { return iterator; }
    return wrapper;
})
