then(function(instance) {
                successCallback(instance, wasmModule);
            }, function(error) {
                self.error = error;
                setStatus("Error");
            });
            return {};
        };

        Module.locateFile = Module.locateFile || function(filename) {
            return config.path + filename;
        };

        // Attach status callbacks
        Module.setStatus = Module.setStatus || function(text) {
            // Currently the only usable status update from this function
            // is "Running..."
            if (text.startsWith("Running"))
                setStatus("Running");
        };
        Module.monitorRunDependencies = Module.monitorRunDependencies || function(left) {
          //  console.log("monitorRunDependencies " + left)
        };

        // Attach standard out/err callbacks.
        Module.print = Module.print || function(text) {
            if (config.stdoutEnabled)
                console.log(text)
        };
        Module.printErr = Module.printErr || function(text) {
            // Filter out OpenGL getProcAddress warnings. Qt tries to resolve
            // all possible function/extension names at startup which causes
            // emscripten to spam the console log with warnings.
            if (text.startsWith !== undefined && text.startsWith("bad name in getProcAddress:"))
                return;

            if (config.stderrEnabled)
                console.log(text)
        };

        // Error handling: set status to "Exited", update crashed and
        // exitCode according to exit type.
        // Emscripten will typically call printErr with the error text
        // as well. Note that emscripten may also throw exceptions from
        // async callbacks. These should be handled in window.onerror by user code.
        Module.onAbort = Module.onAbort || function(text) {
            publicAPI.crashed = true;
            publicAPI.exitText = text;
            setStatus("Exited");
        };
        Module.quit = Module.quit || function(code, exception) {
            if (exception.name == "ExitStatus") {
                // Clean exit with code
                publicAPI.exitText = undefined
                publicAPI.exitCode = code;
            } else {
                publicAPI.exitText = exception.toString();
                publicAPI.crashed = true;
            }
            setStatus("Exited");
        };

        // Set environment variables
        Module.preRun = Module.preRun || []
        Module.preRun.push(function() {
            for (var [key, value] of Object.entries(config.environment)) {
                ENV[key.toUpperCase()] = value;
            }
        });

        Module.mainScriptUrlOrBlob = new Blob([emscriptenModuleSource], {type: 'text/javascript'});

        Module.qtCanvasElements = config.canvasElements;

        config.restart = function() {

            // Restart by reloading the page. This will wipe all state which means
            // reload loops can't be prevented.
            if (config.restartType == "ReloadPage") {
                location.reload();
            }

            // Restart by readling the emscripten app module.
            ++self.restartCount;
            if (self.restartCount > config.restartLimit) {
                self.error = "Error: This application has crashed too many times and has been disabled. Reload the page to try again."
                setStatus("Error");
                return;
            }
            loadEmscriptenModule(applicationName);
        };

        publicAPI.exitCode = undefined;
        publicAPI.exitText = undefined;
        publicAPI.crashed = false;

        // Finally evaluate the emscripten application script, which will
        // reference the global Module object created above.
        self.eval(emscriptenModuleSource); // ES5 indirect global scope eval
    }

    function setErrorContent() {
        if (config.containerElements === undefined) {
            if (config.showError !== undefined)
                config.showError(self.error);
            return;
        }

        for (container of config.containerElements) {
            var errorElement = config.showError(self.error, container);
            container.appendChild(errorElement);
        }
    }

    function setLoaderContent() {
        if (config.containerElements === undefined) {
            if (config.showLoader !== undefined)
                config.showLoader(self.loaderSubState);
            return;
        }

        for (container of config.containerElements) {
            var loaderElement = config.showLoader(self.loaderSubState, container);
            container.appendChild(loaderElement);
        }
    }

    function setCanvasContent() {
        if (config.containerElements === undefined) {
            if (config.showCanvas !== undefined)
                config.showCanvas();
            return;
        }

        for (var i = 0; i < config.containerElements.length; ++i) {
            var container = config.containerElements[i];
            var canvas = config.canvasElements[i];
            config.showCanvas(canvas, container);
            container.appendChild(canvas);
        }
    }

    function setExitContent() {

        // publicAPI.crashed = true;

        if (publicAPI.status != "Exited")
            return;

        if (config.containerElements === undefined) {
            if (config.showExit !== undefined)
                config.showExit(publicAPI.crashed, publicAPI.exitCode);
            return;
        }

        if (!publicAPI.crashed)
            return;

        for (container of config.containerElements) {
            var loaderElement = config.showExit(publicAPI.crashed, publicAPI.exitCode, container);
            if (loaderElement !== undefined)
                container.appendChild(loaderElement);
        }
    }

    var committedStatus = undefined;
    function handleStatusChange() {
        if (publicAPI.status != "Loading" && committedStatus == publicAPI.status)
            return;
        committedStatus = publicAPI.status;

        if (publicAPI.status == "Error") {
            setErrorContent();
        } else if (publicAPI.status == "Loading") {
            setLoaderContent();
        } else if (publicAPI.status == "Running") {
            setCanvasContent();
        } else if (publicAPI.status == "Exited") {
            if (config.restartMode == "RestartOnExit" ||
                config.restartMode == "RestartOnCrash" && publicAPI.crashed) {
                    committedStatus = undefined;
                    config.restart();
            } else {
                setExitContent();
            }
        }

        // Send status change notification
        if (config.statusChanged)
            config.statusChanged(publicAPI.status);
    }

    function setStatus(status) {
        if (status != "Loading" && publicAPI.status == status)
            return;
        publicAPI.status = status;

        window.setTimeout(function() { handleStatusChange(); }, 0);
    }

    function addCanvasElement(element) {
        if (publicAPI.status == "Running")
            Module.qtAddCanvasElement(element);
        else
            console.log("Error: addCanvasElement can only be called in the Running state");
    }

    function removeCanvasElement(element) {
        if (publicAPI.status == "Running")
            Module.qtRemoveCanvasElement(element);
        else
            console.log("Error: removeCanvasElement can only be called in the Running state");
    }

    function resizeCanvasElement(element) {
        if (publicAPI.status == "Running")
            Module.qtResizeCanvasElement(element);
    }

    function setFontDpi(dpi) {
        Module.qtFontDpi = dpi;
        if (publicAPI.status == "Running")
            Module.qtSetFontDpi(dpi);
    }

    function fontDpi() {
        return Module.qtFontDpi;
    }

    setStatus("Created");

    return publicAPI;
}
Ә