diff options
Diffstat (limited to 'platform/javascript')
51 files changed, 0 insertions, 15297 deletions
diff --git a/platform/javascript/.eslintrc.engine.js b/platform/javascript/.eslintrc.engine.js deleted file mode 100644 index 78df6d41d9..0000000000 --- a/platform/javascript/.eslintrc.engine.js +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = { - "extends": [ - "./.eslintrc.js", - ], - "globals": { - "InternalConfig": true, - "Godot": true, - "Preloader": true, - }, -}; diff --git a/platform/javascript/.eslintrc.js b/platform/javascript/.eslintrc.js deleted file mode 100644 index 2c81f1f02d..0000000000 --- a/platform/javascript/.eslintrc.js +++ /dev/null @@ -1,51 +0,0 @@ -module.exports = { - "env": { - "browser": true, - "es2021": true, - }, - "extends": [ - "airbnb-base", - ], - "parserOptions": { - "ecmaVersion": 12, - }, - "ignorePatterns": "*.externs.js", - "rules": { - "func-names": "off", - // Use tabs for consistency with the C++ codebase. - "indent": ["error", "tab"], - "max-len": "off", - "no-else-return": ["error", {allowElseIf: true}], - "curly": ["error", "all"], - "brace-style": ["error", "1tbs", { "allowSingleLine": false }], - "no-bitwise": "off", - "no-continue": "off", - "no-self-assign": "off", - "no-tabs": "off", - "no-param-reassign": ["error", { "props": false }], - "no-plusplus": "off", - "no-unused-vars": ["error", { "args": "none" }], - "prefer-destructuring": "off", - "prefer-rest-params": "off", - "prefer-spread": "off", - "camelcase": "off", - "no-underscore-dangle": "off", - "max-classes-per-file": "off", - "prefer-arrow-callback": "off", - // Messes up with copyright headers in source files. - "spaced-comment": "off", - // Completely breaks emscripten libraries. - "object-shorthand": "off", - // Closure compiler (exported properties) - "quote-props": ["error", "consistent"], - "dot-notation": "off", - // No comma dangle for functions (it's madness, and ES2017) - "comma-dangle": ["error", { - "arrays": "always-multiline", - "objects": "always-multiline", - "imports": "always-multiline", - "exports": "always-multiline", - "functions": "never" - }], - } -}; diff --git a/platform/javascript/.eslintrc.libs.js b/platform/javascript/.eslintrc.libs.js deleted file mode 100644 index 8e579fd462..0000000000 --- a/platform/javascript/.eslintrc.libs.js +++ /dev/null @@ -1,26 +0,0 @@ -module.exports = { - "extends": [ - "./.eslintrc.js", - ], - "globals": { - "LibraryManager": true, - "mergeInto": true, - "autoAddDeps": true, - "HEAP8": true, - "HEAPU8": true, - "HEAP32": true, - "HEAPF32": true, - "ERRNO_CODES": true, - "FS": true, - "IDBFS": true, - "GodotOS": true, - "GodotConfig": true, - "GodotEventListeners": true, - "GodotRuntime": true, - "GodotFS": true, - "IDHandler": true, - "Browser": true, - "GL": true, - "XRWebGLLayer": true, - }, -}; diff --git a/platform/javascript/README.md b/platform/javascript/README.md deleted file mode 100644 index f181bea9e0..0000000000 --- a/platform/javascript/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# HTML5 platform port - -This folder contains the C++ and JavaScript code for the HTML5/WebAssembly platform port, -compiled using [Emscripten](https://emscripten.org/). - -It also contains a ESLint linting setup (see [`package.json`](package.json)). - -See also [`misc/dist/html`](/misc/dist/html) folder for files used by this platform -such as the HTML5 shell. - -## Artwork license - -[`logo.png`](logo.png) and [`run_icon.png`](run_icon.png) are licensed under -[Creative Commons Attribution 3.0 Unported](https://www.w3.org/html/logo/faq.html#how-licenced) -per the HTML5 logo usage guidelines. diff --git a/platform/javascript/SCsub b/platform/javascript/SCsub deleted file mode 100644 index 8d9ba82fd4..0000000000 --- a/platform/javascript/SCsub +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/env python - -Import("env") - -javascript_files = [ - "audio_driver_javascript.cpp", - "display_server_javascript.cpp", - "http_client_javascript.cpp", - "javascript_singleton.cpp", - "javascript_main.cpp", - "os_javascript.cpp", - "api/javascript_tools_editor_plugin.cpp", -] - -sys_env = env.Clone() -sys_env.AddJSLibraries( - [ - "js/libs/library_godot_audio.js", - "js/libs/library_godot_display.js", - "js/libs/library_godot_fetch.js", - "js/libs/library_godot_os.js", - "js/libs/library_godot_runtime.js", - "js/libs/library_godot_input.js", - ] -) - -if env["javascript_eval"]: - sys_env.AddJSLibraries(["js/libs/library_godot_javascript_singleton.js"]) - -for lib in sys_env["JS_LIBS"]: - sys_env.Append(LINKFLAGS=["--js-library", lib.abspath]) -for js in env["JS_PRE"]: - sys_env.Append(LINKFLAGS=["--pre-js", js.abspath]) -for ext in env["JS_EXTERNS"]: - sys_env["ENV"]["EMCC_CLOSURE_ARGS"] += " --externs " + ext.abspath - -build = [] -if env["gdnative_enabled"]: - build_targets = ["#bin/godot${PROGSUFFIX}.js", "#bin/godot${PROGSUFFIX}.wasm"] - # Reset libraries. The main runtime will only link emscripten libraries, not godot ones. - sys_env["LIBS"] = [] - # We use IDBFS. Since Emscripten 1.39.1 it needs to be linked explicitly. - sys_env.Append(LIBS=["idbfs.js"]) - # Configure it as a main module (dynamic linking support). - sys_env.Append(CCFLAGS=["-s", "MAIN_MODULE=1"]) - sys_env.Append(LINKFLAGS=["-s", "MAIN_MODULE=1"]) - sys_env.Append(CCFLAGS=["-s", "EXPORT_ALL=1"]) - sys_env.Append(LINKFLAGS=["-s", "EXPORT_ALL=1"]) - sys_env.Append(LINKFLAGS=["-s", "WARN_ON_UNDEFINED_SYMBOLS=0"]) - # Force exporting the standard library (printf, malloc, etc.) - sys_env["ENV"]["EMCC_FORCE_STDLIBS"] = "libc,libc++,libc++abi" - # The main emscripten runtime, with exported standard libraries. - sys = sys_env.Program(build_targets, ["javascript_runtime.cpp"]) - - # The side library, containing all Godot code. - wasm_env = env.Clone() - wasm_env.Append(CPPDEFINES=["WASM_GDNATIVE"]) # So that OS knows it can run GDNative libraries. - wasm_env.Append(CCFLAGS=["-s", "SIDE_MODULE=2"]) - wasm_env.Append(LINKFLAGS=["-s", "SIDE_MODULE=2"]) - wasm = wasm_env.add_program("#bin/godot.side${PROGSUFFIX}.wasm", javascript_files) - build = [sys[0], sys[1], wasm[0]] -else: - build_targets = ["#bin/godot${PROGSUFFIX}.js", "#bin/godot${PROGSUFFIX}.wasm"] - if env["threads_enabled"]: - build_targets.append("#bin/godot${PROGSUFFIX}.worker.js") - # We use IDBFS. Since Emscripten 1.39.1 it needs to be linked explicitly. - sys_env.Append(LIBS=["idbfs.js"]) - build = sys_env.Program(build_targets, javascript_files + ["javascript_runtime.cpp"]) - -sys_env.Depends(build[0], sys_env["JS_LIBS"]) -sys_env.Depends(build[0], sys_env["JS_PRE"]) -sys_env.Depends(build[0], sys_env["JS_EXTERNS"]) - -engine = [ - "js/engine/preloader.js", - "js/engine/config.js", - "js/engine/engine.js", -] -externs = [env.File("#platform/javascript/js/engine/engine.externs.js")] -js_engine = env.CreateEngineFile("#bin/godot${PROGSUFFIX}.engine.js", engine, externs) -env.Depends(js_engine, externs) - -wrap_list = [ - build[0], - js_engine, -] -js_wrapped = env.Textfile("#bin/godot", [env.File(f) for f in wrap_list], TEXTFILESUFFIX="${PROGSUFFIX}.wrapped.js") - -# Extra will be the thread worker, or the GDNative side, or None -extra = build[2] if len(build) > 2 else None -env.CreateTemplateZip(js_wrapped, build[1], extra) diff --git a/platform/javascript/api/api.cpp b/platform/javascript/api/api.cpp deleted file mode 100644 index 46a0a816bf..0000000000 --- a/platform/javascript/api/api.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/*************************************************************************/ -/* api.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "api.h" -#include "core/config/engine.h" -#include "javascript_singleton.h" -#include "javascript_tools_editor_plugin.h" - -static JavaScript *javascript_eval; - -void register_javascript_api() { - JavaScriptToolsEditorPlugin::initialize(); - GDREGISTER_ABSTRACT_CLASS(JavaScriptObject); - GDREGISTER_ABSTRACT_CLASS(JavaScript); - javascript_eval = memnew(JavaScript); - Engine::get_singleton()->add_singleton(Engine::Singleton("JavaScript", javascript_eval)); -} - -void unregister_javascript_api() { - memdelete(javascript_eval); -} - -JavaScript *JavaScript::singleton = nullptr; - -JavaScript *JavaScript::get_singleton() { - return singleton; -} - -JavaScript::JavaScript() { - ERR_FAIL_COND_MSG(singleton != nullptr, "JavaScript singleton already exist."); - singleton = this; -} - -JavaScript::~JavaScript() {} - -void JavaScript::_bind_methods() { - ClassDB::bind_method(D_METHOD("eval", "code", "use_global_execution_context"), &JavaScript::eval, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("get_interface", "interface"), &JavaScript::get_interface); - ClassDB::bind_method(D_METHOD("create_callback", "callable"), &JavaScript::create_callback); - { - MethodInfo mi; - mi.name = "create_object"; - mi.arguments.push_back(PropertyInfo(Variant::STRING, "object")); - ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "create_object", &JavaScript::_create_object_bind, mi); - } - ClassDB::bind_method(D_METHOD("download_buffer", "buffer", "name", "mime"), &JavaScript::download_buffer, DEFVAL("application/octet-stream")); - ClassDB::bind_method(D_METHOD("pwa_needs_update"), &JavaScript::pwa_needs_update); - ClassDB::bind_method(D_METHOD("pwa_update"), &JavaScript::pwa_update); - ADD_SIGNAL(MethodInfo("pwa_update_available")); -} - -#if !defined(JAVASCRIPT_ENABLED) || !defined(JAVASCRIPT_EVAL_ENABLED) -Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) { - return Variant(); -} - -Ref<JavaScriptObject> JavaScript::get_interface(const String &p_interface) { - return Ref<JavaScriptObject>(); -} - -Ref<JavaScriptObject> JavaScript::create_callback(const Callable &p_callable) { - return Ref<JavaScriptObject>(); -} - -Variant JavaScript::_create_object_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { - if (p_argcount < 1) { - r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; - r_error.argument = 0; - return Ref<JavaScriptObject>(); - } - if (p_args[0]->get_type() != Variant::STRING) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::STRING; - return Ref<JavaScriptObject>(); - } - return Ref<JavaScriptObject>(); -} -#endif -#if !defined(JAVASCRIPT_ENABLED) -bool JavaScript::pwa_needs_update() const { - return false; -} -Error JavaScript::pwa_update() { - return ERR_UNAVAILABLE; -} -void JavaScript::download_buffer(Vector<uint8_t> p_arr, const String &p_name, const String &p_mime) { -} -#endif diff --git a/platform/javascript/api/api.h b/platform/javascript/api/api.h deleted file mode 100644 index 97e06c8577..0000000000 --- a/platform/javascript/api/api.h +++ /dev/null @@ -1,37 +0,0 @@ -/*************************************************************************/ -/* api.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef JAVASCRIPT_API_H -#define JAVASCRIPT_API_H - -void register_javascript_api(); -void unregister_javascript_api(); - -#endif // JAVASCRIPT_API_H diff --git a/platform/javascript/api/javascript_singleton.h b/platform/javascript/api/javascript_singleton.h deleted file mode 100644 index e93b0a18a1..0000000000 --- a/platform/javascript/api/javascript_singleton.h +++ /dev/null @@ -1,70 +0,0 @@ -/*************************************************************************/ -/* javascript_singleton.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef JAVASCRIPT_SINGLETON_H -#define JAVASCRIPT_SINGLETON_H - -#include "core/object/class_db.h" -#include "core/object/ref_counted.h" - -class JavaScriptObject : public RefCounted { -private: - GDCLASS(JavaScriptObject, RefCounted); - -protected: - virtual bool _set(const StringName &p_name, const Variant &p_value) { return false; } - virtual bool _get(const StringName &p_name, Variant &r_ret) const { return false; } - virtual void _get_property_list(List<PropertyInfo> *p_list) const {} -}; - -class JavaScript : public Object { -private: - GDCLASS(JavaScript, Object); - - static JavaScript *singleton; - -protected: - static void _bind_methods(); - -public: - Variant eval(const String &p_code, bool p_use_global_exec_context = false); - Ref<JavaScriptObject> get_interface(const String &p_interface); - Ref<JavaScriptObject> create_callback(const Callable &p_callable); - Variant _create_object_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); - void download_buffer(Vector<uint8_t> p_arr, const String &p_name, const String &p_mime = "application/octet-stream"); - bool pwa_needs_update() const; - Error pwa_update(); - - static JavaScript *get_singleton(); - JavaScript(); - ~JavaScript(); -}; - -#endif // JAVASCRIPT_SINGLETON_H diff --git a/platform/javascript/api/javascript_tools_editor_plugin.cpp b/platform/javascript/api/javascript_tools_editor_plugin.cpp deleted file mode 100644 index 1507f32375..0000000000 --- a/platform/javascript/api/javascript_tools_editor_plugin.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/*************************************************************************/ -/* javascript_tools_editor_plugin.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#if defined(TOOLS_ENABLED) && defined(JAVASCRIPT_ENABLED) -#include "javascript_tools_editor_plugin.h" - -#include "core/config/engine.h" -#include "core/config/project_settings.h" -#include "core/io/dir_access.h" -#include "core/io/file_access.h" -#include "core/os/time.h" -#include "editor/editor_node.h" - -#include <emscripten/emscripten.h> - -// JavaScript functions defined in library_godot_editor_tools.js -extern "C" { -extern void godot_js_os_download_buffer(const uint8_t *p_buf, int p_buf_size, const char *p_name, const char *p_mime); -} - -static void _javascript_editor_init_callback() { - EditorNode::get_singleton()->add_editor_plugin(memnew(JavaScriptToolsEditorPlugin)); -} - -void JavaScriptToolsEditorPlugin::initialize() { - EditorNode::add_init_callback(_javascript_editor_init_callback); -} - -JavaScriptToolsEditorPlugin::JavaScriptToolsEditorPlugin() { - add_tool_menu_item("Download Project Source", callable_mp(this, &JavaScriptToolsEditorPlugin::_download_zip)); -} - -void JavaScriptToolsEditorPlugin::_download_zip(Variant p_v) { - if (!Engine::get_singleton() || !Engine::get_singleton()->is_editor_hint()) { - ERR_PRINT("Downloading the project as a ZIP archive is only available in Editor mode."); - return; - } - String resource_path = ProjectSettings::get_singleton()->get_resource_path(); - - Ref<FileAccess> io_fa; - zlib_filefunc_def io = zipio_create_io(&io_fa); - - // Name the downloaded ZIP file to contain the project name and download date for easier organization. - // Replace characters not allowed (or risky) in Windows file names with safe characters. - // In the project name, all invalid characters become an empty string so that a name - // like "Platformer 2: Godette's Revenge" becomes "platformer_2-_godette-s_revenge". - const String project_name = GLOBAL_GET("application/config/name"); - const String project_name_safe = project_name.to_lower().replace(" ", "_"); - const String datetime_safe = - Time::get_singleton()->get_datetime_string_from_system(false, true).replace(" ", "_"); - const String output_name = OS::get_singleton()->get_safe_dir_name(vformat("%s_%s.zip")); - const String output_path = String("/tmp").plus_file(output_name); - - zipFile zip = zipOpen2(output_path.utf8().get_data(), APPEND_STATUS_CREATE, nullptr, &io); - const String base_path = resource_path.substr(0, resource_path.rfind("/")) + "/"; - _zip_recursive(resource_path, base_path, zip); - zipClose(zip, nullptr); - { - Ref<FileAccess> f = FileAccess::open(output_path, FileAccess::READ); - ERR_FAIL_COND_MSG(f.is_null(), "Unable to create ZIP file."); - Vector<uint8_t> buf; - buf.resize(f->get_length()); - f->get_buffer(buf.ptrw(), buf.size()); - godot_js_os_download_buffer(buf.ptr(), buf.size(), output_name.utf8().get_data(), "application/zip"); - } - - // Remove the temporary file since it was sent to the user's native filesystem as a download. - DirAccess::remove_file_or_error(output_path); -} - -void JavaScriptToolsEditorPlugin::_zip_file(String p_path, String p_base_path, zipFile p_zip) { - Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ); - if (f.is_null()) { - WARN_PRINT("Unable to open file for zipping: " + p_path); - return; - } - Vector<uint8_t> data; - uint64_t len = f->get_length(); - data.resize(len); - f->get_buffer(data.ptrw(), len); - - String path = p_path.replace_first(p_base_path, ""); - zipOpenNewFileInZip(p_zip, - path.utf8().get_data(), - nullptr, - nullptr, - 0, - nullptr, - 0, - nullptr, - Z_DEFLATED, - Z_DEFAULT_COMPRESSION); - zipWriteInFileInZip(p_zip, data.ptr(), data.size()); - zipCloseFileInZip(p_zip); -} - -void JavaScriptToolsEditorPlugin::_zip_recursive(String p_path, String p_base_path, zipFile p_zip) { - Ref<DirAccess> dir = DirAccess::open(p_path); - if (dir.is_null()) { - WARN_PRINT("Unable to open directory for zipping: " + p_path); - return; - } - dir->list_dir_begin(); - String cur = dir->get_next(); - String project_data_dir_name = ProjectSettings::get_singleton()->get_project_data_dir_name(); - while (!cur.is_empty()) { - String cs = p_path.plus_file(cur); - if (cur == "." || cur == ".." || cur == project_data_dir_name) { - // Skip - } else if (dir->current_is_dir()) { - String path = cs.replace_first(p_base_path, "") + "/"; - zipOpenNewFileInZip(p_zip, - path.utf8().get_data(), - nullptr, - nullptr, - 0, - nullptr, - 0, - nullptr, - Z_DEFLATED, - Z_DEFAULT_COMPRESSION); - zipCloseFileInZip(p_zip); - _zip_recursive(cs, p_base_path, p_zip); - } else { - _zip_file(cs, p_base_path, p_zip); - } - cur = dir->get_next(); - } -} -#endif diff --git a/platform/javascript/api/javascript_tools_editor_plugin.h b/platform/javascript/api/javascript_tools_editor_plugin.h deleted file mode 100644 index cbf5f49497..0000000000 --- a/platform/javascript/api/javascript_tools_editor_plugin.h +++ /dev/null @@ -1,58 +0,0 @@ -/*************************************************************************/ -/* javascript_tools_editor_plugin.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef JAVASCRIPT_TOOLS_EDITOR_PLUGIN_H -#define JAVASCRIPT_TOOLS_EDITOR_PLUGIN_H - -#if defined(TOOLS_ENABLED) && defined(JAVASCRIPT_ENABLED) -#include "core/io/zip_io.h" -#include "editor/editor_plugin.h" - -class JavaScriptToolsEditorPlugin : public EditorPlugin { - GDCLASS(JavaScriptToolsEditorPlugin, EditorPlugin); - -private: - void _zip_file(String p_path, String p_base_path, zipFile p_zip); - void _zip_recursive(String p_path, String p_base_path, zipFile p_zip); - void _download_zip(Variant p_v); - -public: - static void initialize(); - - JavaScriptToolsEditorPlugin(); -}; -#else -class JavaScriptToolsEditorPlugin { -public: - static void initialize() {} -}; -#endif - -#endif // JAVASCRIPT_TOOLS_EDITOR_PLUGIN_H diff --git a/platform/javascript/audio_driver_javascript.cpp b/platform/javascript/audio_driver_javascript.cpp deleted file mode 100644 index d45885b8e8..0000000000 --- a/platform/javascript/audio_driver_javascript.cpp +++ /dev/null @@ -1,293 +0,0 @@ -/*************************************************************************/ -/* audio_driver_javascript.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "audio_driver_javascript.h" - -#include "core/config/project_settings.h" - -#include <emscripten.h> - -AudioDriverJavaScript::AudioContext AudioDriverJavaScript::audio_context; - -bool AudioDriverJavaScript::is_available() { - return godot_audio_is_available() != 0; -} - -void AudioDriverJavaScript::_state_change_callback(int p_state) { - AudioDriverJavaScript::audio_context.state = p_state; -} - -void AudioDriverJavaScript::_latency_update_callback(float p_latency) { - AudioDriverJavaScript::audio_context.output_latency = p_latency; -} - -void AudioDriverJavaScript::_audio_driver_process(int p_from, int p_samples) { - int32_t *stream_buffer = reinterpret_cast<int32_t *>(output_rb); - const int max_samples = memarr_len(output_rb); - - int write_pos = p_from; - int to_write = p_samples; - if (to_write == 0) { - to_write = max_samples; - } - // High part - if (write_pos + to_write > max_samples) { - const int samples_high = max_samples - write_pos; - audio_server_process(samples_high / channel_count, &stream_buffer[write_pos]); - for (int i = write_pos; i < max_samples; i++) { - output_rb[i] = float(stream_buffer[i] >> 16) / 32768.f; - } - to_write -= samples_high; - write_pos = 0; - } - // Leftover - audio_server_process(to_write / channel_count, &stream_buffer[write_pos]); - for (int i = write_pos; i < write_pos + to_write; i++) { - output_rb[i] = float(stream_buffer[i] >> 16) / 32768.f; - } -} - -void AudioDriverJavaScript::_audio_driver_capture(int p_from, int p_samples) { - if (get_input_buffer().size() == 0) { - return; // Input capture stopped. - } - const int max_samples = memarr_len(input_rb); - - int read_pos = p_from; - int to_read = p_samples; - if (to_read == 0) { - to_read = max_samples; - } - // High part - if (read_pos + to_read > max_samples) { - const int samples_high = max_samples - read_pos; - for (int i = read_pos; i < max_samples; i++) { - input_buffer_write(int32_t(input_rb[i] * 32768.f) * (1U << 16)); - } - to_read -= samples_high; - read_pos = 0; - } - // Leftover - for (int i = read_pos; i < read_pos + to_read; i++) { - input_buffer_write(int32_t(input_rb[i] * 32768.f) * (1U << 16)); - } -} - -Error AudioDriverJavaScript::init() { - int latency = GLOBAL_GET("audio/driver/output_latency"); - if (!audio_context.inited) { - audio_context.mix_rate = GLOBAL_GET("audio/driver/mix_rate"); - audio_context.channel_count = godot_audio_init(&audio_context.mix_rate, latency, &_state_change_callback, &_latency_update_callback); - audio_context.inited = true; - } - mix_rate = audio_context.mix_rate; - channel_count = audio_context.channel_count; - buffer_length = closest_power_of_2((latency * mix_rate / 1000)); - Error err = create(buffer_length, channel_count); - if (err != OK) { - return err; - } - if (output_rb) { - memdelete_arr(output_rb); - } - const size_t array_size = buffer_length * (size_t)channel_count; - output_rb = memnew_arr(float, array_size); - if (!output_rb) { - return ERR_OUT_OF_MEMORY; - } - if (input_rb) { - memdelete_arr(input_rb); - } - input_rb = memnew_arr(float, array_size); - if (!input_rb) { - return ERR_OUT_OF_MEMORY; - } - return OK; -} - -void AudioDriverJavaScript::start() { - start(output_rb, memarr_len(output_rb), input_rb, memarr_len(input_rb)); -} - -void AudioDriverJavaScript::resume() { - if (audio_context.state == 0) { // 'suspended' - godot_audio_resume(); - } -} - -float AudioDriverJavaScript::get_latency() { - return audio_context.output_latency + (float(buffer_length) / mix_rate); -} - -int AudioDriverJavaScript::get_mix_rate() const { - return mix_rate; -} - -AudioDriver::SpeakerMode AudioDriverJavaScript::get_speaker_mode() const { - return get_speaker_mode_by_total_channels(channel_count); -} - -void AudioDriverJavaScript::finish() { - finish_driver(); - if (output_rb) { - memdelete_arr(output_rb); - output_rb = nullptr; - } - if (input_rb) { - memdelete_arr(input_rb); - input_rb = nullptr; - } -} - -Error AudioDriverJavaScript::capture_start() { - lock(); - input_buffer_init(buffer_length); - unlock(); - if (godot_audio_capture_start()) { - return FAILED; - } - return OK; -} - -Error AudioDriverJavaScript::capture_stop() { - godot_audio_capture_stop(); - lock(); - input_buffer.clear(); - unlock(); - return OK; -} - -#ifdef NO_THREADS -/// ScriptProcessorNode implementation -AudioDriverScriptProcessor *AudioDriverScriptProcessor::singleton = nullptr; - -void AudioDriverScriptProcessor::_process_callback() { - AudioDriverScriptProcessor::singleton->_audio_driver_capture(); - AudioDriverScriptProcessor::singleton->_audio_driver_process(); -} - -Error AudioDriverScriptProcessor::create(int &p_buffer_samples, int p_channels) { - if (!godot_audio_has_script_processor()) { - return ERR_UNAVAILABLE; - } - return (Error)godot_audio_script_create(&p_buffer_samples, p_channels); -} - -void AudioDriverScriptProcessor::start(float *p_out_buf, int p_out_buf_size, float *p_in_buf, int p_in_buf_size) { - godot_audio_script_start(p_in_buf, p_in_buf_size, p_out_buf, p_out_buf_size, &_process_callback); -} - -/// AudioWorkletNode implementation (no threads) -AudioDriverWorklet *AudioDriverWorklet::singleton = nullptr; - -Error AudioDriverWorklet::create(int &p_buffer_size, int p_channels) { - if (!godot_audio_has_worklet()) { - return ERR_UNAVAILABLE; - } - return (Error)godot_audio_worklet_create(p_channels); -} - -void AudioDriverWorklet::start(float *p_out_buf, int p_out_buf_size, float *p_in_buf, int p_in_buf_size) { - _audio_driver_process(); - godot_audio_worklet_start_no_threads(p_out_buf, p_out_buf_size, &_process_callback, p_in_buf, p_in_buf_size, &_capture_callback); -} - -void AudioDriverWorklet::_process_callback(int p_pos, int p_samples) { - AudioDriverWorklet *driver = AudioDriverWorklet::singleton; - driver->_audio_driver_process(p_pos, p_samples); -} - -void AudioDriverWorklet::_capture_callback(int p_pos, int p_samples) { - AudioDriverWorklet *driver = AudioDriverWorklet::singleton; - driver->_audio_driver_capture(p_pos, p_samples); -} -#else -/// AudioWorkletNode implementation (threads) -void AudioDriverWorklet::_audio_thread_func(void *p_data) { - AudioDriverWorklet *driver = static_cast<AudioDriverWorklet *>(p_data); - const int out_samples = memarr_len(driver->get_output_rb()); - const int in_samples = memarr_len(driver->get_input_rb()); - int wpos = 0; - int to_write = out_samples; - int rpos = 0; - int to_read = 0; - int32_t step = 0; - while (!driver->quit) { - if (to_read) { - driver->lock(); - driver->_audio_driver_capture(rpos, to_read); - godot_audio_worklet_state_add(driver->state, STATE_SAMPLES_IN, -to_read); - driver->unlock(); - rpos += to_read; - if (rpos >= in_samples) { - rpos -= in_samples; - } - } - if (to_write) { - driver->lock(); - driver->_audio_driver_process(wpos, to_write); - godot_audio_worklet_state_add(driver->state, STATE_SAMPLES_OUT, to_write); - driver->unlock(); - wpos += to_write; - if (wpos >= out_samples) { - wpos -= out_samples; - } - } - step = godot_audio_worklet_state_wait(driver->state, STATE_PROCESS, step, 1); - to_write = out_samples - godot_audio_worklet_state_get(driver->state, STATE_SAMPLES_OUT); - to_read = godot_audio_worklet_state_get(driver->state, STATE_SAMPLES_IN); - } -} - -Error AudioDriverWorklet::create(int &p_buffer_size, int p_channels) { - if (!godot_audio_has_worklet()) { - return ERR_UNAVAILABLE; - } - return (Error)godot_audio_worklet_create(p_channels); -} - -void AudioDriverWorklet::start(float *p_out_buf, int p_out_buf_size, float *p_in_buf, int p_in_buf_size) { - godot_audio_worklet_start(p_in_buf, p_in_buf_size, p_out_buf, p_out_buf_size, state); - thread.start(_audio_thread_func, this); -} - -void AudioDriverWorklet::lock() { - mutex.lock(); -} - -void AudioDriverWorklet::unlock() { - mutex.unlock(); -} - -void AudioDriverWorklet::finish_driver() { - quit = true; // Ask thread to quit. - thread.wait_to_finish(); -} -#endif diff --git a/platform/javascript/audio_driver_javascript.h b/platform/javascript/audio_driver_javascript.h deleted file mode 100644 index b7b0b3ac96..0000000000 --- a/platform/javascript/audio_driver_javascript.h +++ /dev/null @@ -1,161 +0,0 @@ -/*************************************************************************/ -/* audio_driver_javascript.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef AUDIO_DRIVER_JAVASCRIPT_H -#define AUDIO_DRIVER_JAVASCRIPT_H - -#include "core/os/mutex.h" -#include "core/os/thread.h" -#include "servers/audio_server.h" - -#include "godot_audio.h" - -class AudioDriverJavaScript : public AudioDriver { -private: - struct AudioContext { - bool inited = false; - float output_latency = 0.0; - int state = -1; - int channel_count = 0; - int mix_rate = 0; - }; - static AudioContext audio_context; - - float *output_rb = nullptr; - float *input_rb = nullptr; - - int buffer_length = 0; - int mix_rate = 0; - int channel_count = 0; - - static void _state_change_callback(int p_state); - static void _latency_update_callback(float p_latency); - - static AudioDriverJavaScript *singleton; - -protected: - void _audio_driver_process(int p_from = 0, int p_samples = 0); - void _audio_driver_capture(int p_from = 0, int p_samples = 0); - float *get_output_rb() const { return output_rb; } - float *get_input_rb() const { return input_rb; } - - virtual Error create(int &p_buffer_samples, int p_channels) = 0; - virtual void start(float *p_out_buf, int p_out_buf_size, float *p_in_buf, int p_in_buf_size) = 0; - virtual void finish_driver() {} - -public: - static bool is_available(); - - virtual Error init() final; - virtual void start() final; - virtual void finish() final; - - virtual float get_latency() override; - virtual int get_mix_rate() const override; - virtual SpeakerMode get_speaker_mode() const override; - - virtual Error capture_start() override; - virtual Error capture_stop() override; - - static void resume(); - - AudioDriverJavaScript() {} -}; - -#ifdef NO_THREADS -class AudioDriverScriptProcessor : public AudioDriverJavaScript { -private: - static void _process_callback(); - - static AudioDriverScriptProcessor *singleton; - -protected: - Error create(int &p_buffer_samples, int p_channels) override; - void start(float *p_out_buf, int p_out_buf_size, float *p_in_buf, int p_in_buf_size) override; - -public: - virtual const char *get_name() const override { return "ScriptProcessor"; } - - virtual void lock() override {} - virtual void unlock() override {} - - AudioDriverScriptProcessor() { singleton = this; } -}; - -class AudioDriverWorklet : public AudioDriverJavaScript { -private: - static void _process_callback(int p_pos, int p_samples); - static void _capture_callback(int p_pos, int p_samples); - - static AudioDriverWorklet *singleton; - -protected: - virtual Error create(int &p_buffer_size, int p_output_channels) override; - virtual void start(float *p_out_buf, int p_out_buf_size, float *p_in_buf, int p_in_buf_size) override; - -public: - virtual const char *get_name() const override { return "AudioWorklet"; } - - virtual void lock() override {} - virtual void unlock() override {} - - AudioDriverWorklet() { singleton = this; } -}; -#else -class AudioDriverWorklet : public AudioDriverJavaScript { -private: - enum { - STATE_LOCK, - STATE_PROCESS, - STATE_SAMPLES_IN, - STATE_SAMPLES_OUT, - STATE_MAX, - }; - Mutex mutex; - Thread thread; - bool quit = false; - int32_t state[STATE_MAX] = { 0 }; - - static void _audio_thread_func(void *p_data); - -protected: - virtual Error create(int &p_buffer_size, int p_output_channels) override; - virtual void start(float *p_out_buf, int p_out_buf_size, float *p_in_buf, int p_in_buf_size) override; - virtual void finish_driver() override; - -public: - virtual const char *get_name() const override { return "AudioWorklet"; } - - void lock() override; - void unlock() override; -}; -#endif - -#endif diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py deleted file mode 100644 index 709104c5ee..0000000000 --- a/platform/javascript/detect.py +++ /dev/null @@ -1,237 +0,0 @@ -import os -import sys - -from emscripten_helpers import ( - run_closure_compiler, - create_engine_file, - add_js_libraries, - add_js_pre, - add_js_externs, - create_template_zip, -) -from methods import get_compiler_version -from SCons.Util import WhereIs - - -def is_active(): - return True - - -def get_name(): - return "JavaScript" - - -def can_build(): - return WhereIs("emcc") is not None - - -def get_opts(): - from SCons.Variables import BoolVariable - - return [ - ("initial_memory", "Initial WASM memory (in MiB)", 32), - BoolVariable("use_assertions", "Use Emscripten runtime assertions", False), - BoolVariable("use_thinlto", "Use ThinLTO", False), - BoolVariable("use_ubsan", "Use Emscripten undefined behavior sanitizer (UBSAN)", False), - BoolVariable("use_asan", "Use Emscripten address sanitizer (ASAN)", False), - BoolVariable("use_lsan", "Use Emscripten leak sanitizer (LSAN)", False), - BoolVariable("use_safe_heap", "Use Emscripten SAFE_HEAP sanitizer", False), - # eval() can be a security concern, so it can be disabled. - BoolVariable("javascript_eval", "Enable JavaScript eval interface", True), - BoolVariable("threads_enabled", "Enable WebAssembly Threads support (limited browser support)", True), - BoolVariable("gdnative_enabled", "Enable WebAssembly GDNative support (produces bigger binaries)", False), - BoolVariable("use_closure_compiler", "Use closure compiler to minimize JavaScript code", False), - ] - - -def get_flags(): - return [ - ("tools", False), - ("builtin_pcre2_with_jit", False), - # Disabling the mbedtls module reduces file size. - # The module has little use due to the limited networking functionality - # in this platform. For the available networking methods, the browser - # manages TLS. - ("module_mbedtls_enabled", False), - ("vulkan", False), - ] - - -def configure(env): - try: - env["initial_memory"] = int(env["initial_memory"]) - except Exception: - print("Initial memory must be a valid integer") - sys.exit(255) - - ## Build type - if env["target"].startswith("release"): - # Use -Os to prioritize optimizing for reduced file size. This is - # particularly valuable for the web platform because it directly - # decreases download time. - # -Os reduces file size by around 5 MiB over -O3. -Oz only saves about - # 100 KiB over -Os, which does not justify the negative impact on - # run-time performance. - if env["optimize"] != "none": - env.Append(CCFLAGS=["-Os"]) - env.Append(LINKFLAGS=["-Os"]) - - if env["target"] == "release_debug": - # Retain function names for backtraces at the cost of file size. - env.Append(LINKFLAGS=["--profiling-funcs"]) - else: # "debug" - env.Append(CCFLAGS=["-O1", "-g"]) - env.Append(LINKFLAGS=["-O1", "-g"]) - env["use_assertions"] = True - - if env["use_assertions"]: - env.Append(LINKFLAGS=["-s", "ASSERTIONS=1"]) - - if env["tools"]: - if not env["threads_enabled"]: - print('Note: Forcing "threads_enabled=yes" as it is required for the web editor.') - env["threads_enabled"] = "yes" - if env["initial_memory"] < 64: - print('Note: Forcing "initial_memory=64" as it is required for the web editor.') - env["initial_memory"] = 64 - env.Append(CCFLAGS=["-frtti"]) - elif env["builtin_icu"]: - env.Append(CCFLAGS=["-fno-exceptions", "-frtti"]) - else: - # Disable exceptions and rtti on non-tools (template) builds - # These flags help keep the file size down. - env.Append(CCFLAGS=["-fno-exceptions", "-fno-rtti"]) - # Don't use dynamic_cast, necessary with no-rtti. - env.Append(CPPDEFINES=["NO_SAFE_CAST"]) - - env.Append(LINKFLAGS=["-s", "INITIAL_MEMORY=%sMB" % env["initial_memory"]]) - - ## Copy env variables. - env["ENV"] = os.environ - - # LTO - if env["use_thinlto"]: - env.Append(CCFLAGS=["-flto=thin"]) - env.Append(LINKFLAGS=["-flto=thin"]) - elif env["use_lto"]: - env.Append(CCFLAGS=["-flto=full"]) - env.Append(LINKFLAGS=["-flto=full"]) - - # Sanitizers - if env["use_ubsan"]: - env.Append(CCFLAGS=["-fsanitize=undefined"]) - env.Append(LINKFLAGS=["-fsanitize=undefined"]) - if env["use_asan"]: - env.Append(CCFLAGS=["-fsanitize=address"]) - env.Append(LINKFLAGS=["-fsanitize=address"]) - if env["use_lsan"]: - env.Append(CCFLAGS=["-fsanitize=leak"]) - env.Append(LINKFLAGS=["-fsanitize=leak"]) - if env["use_safe_heap"]: - env.Append(LINKFLAGS=["-s", "SAFE_HEAP=1"]) - - # Closure compiler - if env["use_closure_compiler"]: - # For emscripten support code. - env.Append(LINKFLAGS=["--closure", "1"]) - # Register builder for our Engine files - jscc = env.Builder(generator=run_closure_compiler, suffix=".cc.js", src_suffix=".js") - env.Append(BUILDERS={"BuildJS": jscc}) - - # Add helper method for adding libraries, externs, pre-js. - env["JS_LIBS"] = [] - env["JS_PRE"] = [] - env["JS_EXTERNS"] = [] - env.AddMethod(add_js_libraries, "AddJSLibraries") - env.AddMethod(add_js_pre, "AddJSPre") - env.AddMethod(add_js_externs, "AddJSExterns") - - # Add method that joins/compiles our Engine files. - env.AddMethod(create_engine_file, "CreateEngineFile") - - # Add method for creating the final zip file - env.AddMethod(create_template_zip, "CreateTemplateZip") - - # Closure compiler extern and support for ecmascript specs (const, let, etc). - env["ENV"]["EMCC_CLOSURE_ARGS"] = "--language_in ECMASCRIPT6" - - env["CC"] = "emcc" - env["CXX"] = "em++" - - env["AR"] = "emar" - env["RANLIB"] = "emranlib" - - # Use TempFileMunge since some AR invocations are too long for cmd.exe. - # Use POSIX-style paths, required with TempFileMunge. - env["ARCOM_POSIX"] = env["ARCOM"].replace("$TARGET", "$TARGET.posix").replace("$SOURCES", "$SOURCES.posix") - env["ARCOM"] = "${TEMPFILE(ARCOM_POSIX)}" - - # All intermediate files are just LLVM bitcode. - env["OBJPREFIX"] = "" - env["OBJSUFFIX"] = ".bc" - env["PROGPREFIX"] = "" - # Program() output consists of multiple files, so specify suffixes manually at builder. - env["PROGSUFFIX"] = "" - env["LIBPREFIX"] = "lib" - env["LIBSUFFIX"] = ".a" - env["LIBPREFIXES"] = ["$LIBPREFIX"] - env["LIBSUFFIXES"] = ["$LIBSUFFIX"] - - env.Prepend(CPPPATH=["#platform/javascript"]) - env.Append(CPPDEFINES=["JAVASCRIPT_ENABLED", "UNIX_ENABLED"]) - - if env["opengl3"]: - env.AppendUnique(CPPDEFINES=["GLES3_ENABLED"]) - # This setting just makes WebGL 2 APIs available, it does NOT disable WebGL 1. - env.Append(LINKFLAGS=["-s", "USE_WEBGL2=1"]) - # Allow use to take control of swapping WebGL buffers. - env.Append(LINKFLAGS=["-s", "OFFSCREEN_FRAMEBUFFER=1"]) - - if env["javascript_eval"]: - env.Append(CPPDEFINES=["JAVASCRIPT_EVAL_ENABLED"]) - - if env["threads_enabled"] and env["gdnative_enabled"]: - print("Threads and GDNative support can't be both enabled due to WebAssembly limitations") - sys.exit(255) - - # Thread support (via SharedArrayBuffer). - if env["threads_enabled"]: - env.Append(CPPDEFINES=["PTHREAD_NO_RENAME"]) - env.Append(CCFLAGS=["-s", "USE_PTHREADS=1"]) - env.Append(LINKFLAGS=["-s", "USE_PTHREADS=1"]) - env.Append(LINKFLAGS=["-s", "PTHREAD_POOL_SIZE=8"]) - env.Append(LINKFLAGS=["-s", "WASM_MEM_MAX=2048MB"]) - env.extra_suffix = ".threads" + env.extra_suffix - else: - env.Append(CPPDEFINES=["NO_THREADS"]) - - if env["gdnative_enabled"]: - major, minor, patch = get_compiler_version(env) - if major < 2 or (major == 2 and minor == 0 and patch < 10): - print("GDNative support requires emscripten >= 2.0.10, detected: %s.%s.%s" % (major, minor, patch)) - sys.exit(255) - env.Append(CCFLAGS=["-s", "RELOCATABLE=1"]) - env.Append(LINKFLAGS=["-s", "RELOCATABLE=1"]) - # Weak symbols are broken upstream: https://github.com/emscripten-core/emscripten/issues/12819 - env.Append(CPPDEFINES=["ZSTD_HAVE_WEAK_SYMBOLS=0"]) - env.extra_suffix = ".gdnative" + env.extra_suffix - - # Reduce code size by generating less support code (e.g. skip NodeJS support). - env.Append(LINKFLAGS=["-s", "ENVIRONMENT=web,worker"]) - - # Wrap the JavaScript support code around a closure named Godot. - env.Append(LINKFLAGS=["-s", "MODULARIZE=1", "-s", "EXPORT_NAME='Godot'"]) - - # Allow increasing memory buffer size during runtime. This is efficient - # when using WebAssembly (in comparison to asm.js) and works well for - # us since we don't know requirements at compile-time. - env.Append(LINKFLAGS=["-s", "ALLOW_MEMORY_GROWTH=1"]) - - # Do not call main immediately when the support code is ready. - env.Append(LINKFLAGS=["-s", "INVOKE_RUN=0"]) - - # callMain for manual start, cwrap for the mono version. - env.Append(LINKFLAGS=["-s", "EXPORTED_RUNTIME_METHODS=['callMain','cwrap']"]) - - # Add code that allow exiting runtime. - env.Append(LINKFLAGS=["-s", "EXIT_RUNTIME=1"]) diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp deleted file mode 100644 index 4013f80d6b..0000000000 --- a/platform/javascript/display_server_javascript.cpp +++ /dev/null @@ -1,1060 +0,0 @@ -/*************************************************************************/ -/* display_server_javascript.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "display_server_javascript.h" - -#ifdef GLES3_ENABLED -#include "drivers/gles3/rasterizer_gles3.h" -#endif -#include "platform/javascript/os_javascript.h" -#include "servers/rendering/dummy/rasterizer_dummy.h" - -#include <emscripten.h> -#include <png.h> - -#include "dom_keys.inc" -#include "godot_js.h" - -#define DOM_BUTTON_LEFT 0 -#define DOM_BUTTON_MIDDLE 1 -#define DOM_BUTTON_RIGHT 2 -#define DOM_BUTTON_XBUTTON1 3 -#define DOM_BUTTON_XBUTTON2 4 - -DisplayServerJavaScript *DisplayServerJavaScript::get_singleton() { - return static_cast<DisplayServerJavaScript *>(DisplayServer::get_singleton()); -} - -// Window (canvas) -bool DisplayServerJavaScript::check_size_force_redraw() { - return godot_js_display_size_update() != 0; -} - -void DisplayServerJavaScript::fullscreen_change_callback(int p_fullscreen) { - DisplayServerJavaScript *display = get_singleton(); - if (p_fullscreen) { - display->window_mode = WINDOW_MODE_FULLSCREEN; - } else { - display->window_mode = WINDOW_MODE_WINDOWED; - } -} - -// Drag and drop callback. -void DisplayServerJavaScript::drop_files_js_callback(char **p_filev, int p_filec) { - DisplayServerJavaScript *ds = get_singleton(); - if (!ds) { - ERR_FAIL_MSG("Unable to drop files because the DisplayServer is not active"); - } - if (ds->drop_files_callback.is_null()) { - return; - } - Vector<String> files; - for (int i = 0; i < p_filec; i++) { - files.push_back(String::utf8(p_filev[i])); - } - Variant v = files; - Variant *vp = &v; - Variant ret; - Callable::CallError ce; - ds->drop_files_callback.call((const Variant **)&vp, 1, ret, ce); -} - -// JavaScript quit request callback. -void DisplayServerJavaScript::request_quit_callback() { - DisplayServerJavaScript *ds = get_singleton(); - if (ds && !ds->window_event_callback.is_null()) { - Variant event = int(DisplayServer::WINDOW_EVENT_CLOSE_REQUEST); - Variant *eventp = &event; - Variant ret; - Callable::CallError ce; - ds->window_event_callback.call((const Variant **)&eventp, 1, ret, ce); - } -} - -// Keys - -void DisplayServerJavaScript::dom2godot_mod(Ref<InputEventWithModifiers> ev, int p_mod) { - ev->set_shift_pressed(p_mod & 1); - ev->set_alt_pressed(p_mod & 2); - ev->set_ctrl_pressed(p_mod & 4); - ev->set_meta_pressed(p_mod & 8); -} - -void DisplayServerJavaScript::key_callback(int p_pressed, int p_repeat, int p_modifiers) { - DisplayServerJavaScript *ds = get_singleton(); - JSKeyEvent &key_event = ds->key_event; - // Resume audio context after input in case autoplay was denied. - OS_JavaScript::get_singleton()->resume_audio(); - - Ref<InputEventKey> ev; - ev.instantiate(); - ev->set_echo(p_repeat); - ev->set_keycode(dom_code2godot_scancode(key_event.code, key_event.key, false)); - ev->set_physical_keycode(dom_code2godot_scancode(key_event.code, key_event.key, true)); - ev->set_pressed(p_pressed); - dom2godot_mod(ev, p_modifiers); - - String unicode = String::utf8(key_event.key); - if (unicode.length() == 1) { - ev->set_unicode(unicode[0]); - } - Input::get_singleton()->parse_input_event(ev); - - // Make sure to flush all events so we can call restricted APIs inside the event. - Input::get_singleton()->flush_buffered_events(); -} - -// Mouse - -int DisplayServerJavaScript::mouse_button_callback(int p_pressed, int p_button, double p_x, double p_y, int p_modifiers) { - DisplayServerJavaScript *ds = get_singleton(); - - Point2 pos(p_x, p_y); - Ref<InputEventMouseButton> ev; - ev.instantiate(); - ev->set_position(pos); - ev->set_global_position(pos); - ev->set_pressed(p_pressed); - dom2godot_mod(ev, p_modifiers); - - switch (p_button) { - case DOM_BUTTON_LEFT: - ev->set_button_index(MouseButton::LEFT); - break; - case DOM_BUTTON_MIDDLE: - ev->set_button_index(MouseButton::MIDDLE); - break; - case DOM_BUTTON_RIGHT: - ev->set_button_index(MouseButton::RIGHT); - break; - case DOM_BUTTON_XBUTTON1: - ev->set_button_index(MouseButton::MB_XBUTTON1); - break; - case DOM_BUTTON_XBUTTON2: - ev->set_button_index(MouseButton::MB_XBUTTON2); - break; - default: - return false; - } - - if (p_pressed) { - uint64_t diff = (OS::get_singleton()->get_ticks_usec() / 1000) - ds->last_click_ms; - - if (ev->get_button_index() == ds->last_click_button_index) { - if (diff < 400 && Point2(ds->last_click_pos).distance_to(ev->get_position()) < 5) { - ds->last_click_ms = 0; - ds->last_click_pos = Point2(-100, -100); - ds->last_click_button_index = MouseButton::NONE; - ev->set_double_click(true); - } - - } else { - ds->last_click_button_index = ev->get_button_index(); - } - - if (!ev->is_double_click()) { - ds->last_click_ms += diff; - ds->last_click_pos = ev->get_position(); - } - } - - MouseButton mask = Input::get_singleton()->get_mouse_button_mask(); - MouseButton button_flag = mouse_button_to_mask(ev->get_button_index()); - if (ev->is_pressed()) { - mask |= button_flag; - } else if ((mask & button_flag) != MouseButton::NONE) { - mask &= ~button_flag; - } else { - // Received release event, but press was outside the canvas, so ignore. - return false; - } - ev->set_button_mask(mask); - - Input::get_singleton()->parse_input_event(ev); - // Resume audio context after input in case autoplay was denied. - OS_JavaScript::get_singleton()->resume_audio(); - - // Make sure to flush all events so we can call restricted APIs inside the event. - Input::get_singleton()->flush_buffered_events(); - - // Prevent multi-click text selection and wheel-click scrolling anchor. - // Context menu is prevented through contextmenu event. - return true; -} - -void DisplayServerJavaScript::mouse_move_callback(double p_x, double p_y, double p_rel_x, double p_rel_y, int p_modifiers) { - MouseButton input_mask = Input::get_singleton()->get_mouse_button_mask(); - // For motion outside the canvas, only read mouse movement if dragging - // started inside the canvas; imitating desktop app behaviour. - if (!get_singleton()->cursor_inside_canvas && input_mask == MouseButton::NONE) { - return; - } - - Point2 pos(p_x, p_y); - Ref<InputEventMouseMotion> ev; - ev.instantiate(); - dom2godot_mod(ev, p_modifiers); - ev->set_button_mask(input_mask); - - ev->set_position(pos); - ev->set_global_position(pos); - - ev->set_relative(Vector2(p_rel_x, p_rel_y)); - ev->set_velocity(Input::get_singleton()->get_last_mouse_velocity()); - - Input::get_singleton()->parse_input_event(ev); -} - -// Cursor -const char *DisplayServerJavaScript::godot2dom_cursor(DisplayServer::CursorShape p_shape) { - switch (p_shape) { - case DisplayServer::CURSOR_ARROW: - return "auto"; - case DisplayServer::CURSOR_IBEAM: - return "text"; - case DisplayServer::CURSOR_POINTING_HAND: - return "pointer"; - case DisplayServer::CURSOR_CROSS: - return "crosshair"; - case DisplayServer::CURSOR_WAIT: - return "progress"; - case DisplayServer::CURSOR_BUSY: - return "wait"; - case DisplayServer::CURSOR_DRAG: - return "grab"; - case DisplayServer::CURSOR_CAN_DROP: - return "grabbing"; - case DisplayServer::CURSOR_FORBIDDEN: - return "no-drop"; - case DisplayServer::CURSOR_VSIZE: - return "ns-resize"; - case DisplayServer::CURSOR_HSIZE: - return "ew-resize"; - case DisplayServer::CURSOR_BDIAGSIZE: - return "nesw-resize"; - case DisplayServer::CURSOR_FDIAGSIZE: - return "nwse-resize"; - case DisplayServer::CURSOR_MOVE: - return "move"; - case DisplayServer::CURSOR_VSPLIT: - return "row-resize"; - case DisplayServer::CURSOR_HSPLIT: - return "col-resize"; - case DisplayServer::CURSOR_HELP: - return "help"; - default: - return "auto"; - } -} - -bool DisplayServerJavaScript::tts_is_speaking() const { - return godot_js_tts_is_speaking(); -} - -bool DisplayServerJavaScript::tts_is_paused() const { - return godot_js_tts_is_paused(); -} - -void DisplayServerJavaScript::update_voices_callback(int p_size, const char **p_voice) { - get_singleton()->voices.clear(); - for (int i = 0; i < p_size; i++) { - Vector<String> tokens = String::utf8(p_voice[i]).split(";", true, 2); - if (tokens.size() == 2) { - Dictionary voice_d; - voice_d["name"] = tokens[1]; - voice_d["id"] = tokens[1]; - voice_d["language"] = tokens[0]; - get_singleton()->voices.push_back(voice_d); - } - } -} - -Array DisplayServerJavaScript::tts_get_voices() const { - godot_js_tts_get_voices(update_voices_callback); - return voices; -} - -void DisplayServerJavaScript::tts_speak(const String &p_text, const String &p_voice, int p_volume, float p_pitch, float p_rate, int p_utterance_id, bool p_interrupt) { - if (p_interrupt) { - tts_stop(); - } - - if (p_text.is_empty()) { - tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_CANCELED, p_utterance_id); - return; - } - - CharString string = p_text.utf8(); - utterance_ids[p_utterance_id] = string; - - godot_js_tts_speak(string.get_data(), p_voice.utf8().get_data(), CLAMP(p_volume, 0, 100), CLAMP(p_pitch, 0.f, 2.f), CLAMP(p_rate, 0.1f, 10.f), p_utterance_id, DisplayServerJavaScript::_js_utterance_callback); -} - -void DisplayServerJavaScript::tts_pause() { - godot_js_tts_pause(); -} - -void DisplayServerJavaScript::tts_resume() { - godot_js_tts_resume(); -} - -void DisplayServerJavaScript::tts_stop() { - for (const KeyValue<int, CharString> &E : utterance_ids) { - tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_CANCELED, E.key); - } - utterance_ids.clear(); - godot_js_tts_stop(); -} - -void DisplayServerJavaScript::_js_utterance_callback(int p_event, int p_id, int p_pos) { - DisplayServerJavaScript *ds = (DisplayServerJavaScript *)DisplayServer::get_singleton(); - if (ds->utterance_ids.has(p_id)) { - int pos = 0; - if ((TTSUtteranceEvent)p_event == DisplayServer::TTS_UTTERANCE_BOUNDARY) { - // Convert position from UTF-8 to UTF-32. - const CharString &string = ds->utterance_ids[p_id]; - for (int i = 0; i < MIN(p_pos, string.length()); i++) { - uint8_t c = string[i]; - if ((c & 0xe0) == 0xc0) { - i += 1; - } else if ((c & 0xf0) == 0xe0) { - i += 2; - } else if ((c & 0xf8) == 0xf0) { - i += 3; - } - pos++; - } - } else if ((TTSUtteranceEvent)p_event != DisplayServer::TTS_UTTERANCE_STARTED) { - ds->utterance_ids.erase(p_id); - } - ds->tts_post_utterance_event((TTSUtteranceEvent)p_event, p_id, pos); - } -} - -void DisplayServerJavaScript::cursor_set_shape(CursorShape p_shape) { - ERR_FAIL_INDEX(p_shape, CURSOR_MAX); - if (cursor_shape == p_shape) { - return; - } - cursor_shape = p_shape; - godot_js_display_cursor_set_shape(godot2dom_cursor(cursor_shape)); -} - -DisplayServer::CursorShape DisplayServerJavaScript::cursor_get_shape() const { - return cursor_shape; -} - -void DisplayServerJavaScript::cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { - if (p_cursor.is_valid()) { - Ref<Texture2D> texture = p_cursor; - Ref<AtlasTexture> atlas_texture = p_cursor; - Ref<Image> image; - Size2 texture_size; - Rect2 atlas_rect; - - if (texture.is_valid()) { - image = texture->get_image(); - } - - if (!image.is_valid() && atlas_texture.is_valid()) { - texture = atlas_texture->get_atlas(); - - atlas_rect.size.width = texture->get_width(); - atlas_rect.size.height = texture->get_height(); - atlas_rect.position.x = atlas_texture->get_region().position.x; - atlas_rect.position.y = atlas_texture->get_region().position.y; - - texture_size.width = atlas_texture->get_region().size.x; - texture_size.height = atlas_texture->get_region().size.y; - } else if (image.is_valid()) { - texture_size.width = texture->get_width(); - texture_size.height = texture->get_height(); - } - - ERR_FAIL_COND(!texture.is_valid()); - ERR_FAIL_COND(p_hotspot.x < 0 || p_hotspot.y < 0); - ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256); - ERR_FAIL_COND(p_hotspot.x > texture_size.width || p_hotspot.y > texture_size.height); - - image = texture->get_image(); - - ERR_FAIL_COND(!image.is_valid()); - - image = image->duplicate(); - - if (atlas_texture.is_valid()) { - image->crop_from_point( - atlas_rect.position.x, - atlas_rect.position.y, - texture_size.width, - texture_size.height); - } - - if (image->get_format() != Image::FORMAT_RGBA8) { - image->convert(Image::FORMAT_RGBA8); - } - - png_image png_meta; - memset(&png_meta, 0, sizeof png_meta); - png_meta.version = PNG_IMAGE_VERSION; - png_meta.width = texture_size.width; - png_meta.height = texture_size.height; - png_meta.format = PNG_FORMAT_RGBA; - - PackedByteArray png; - size_t len; - PackedByteArray data = image->get_data(); - ERR_FAIL_COND(!png_image_write_get_memory_size(png_meta, len, 0, data.ptr(), 0, nullptr)); - - png.resize(len); - ERR_FAIL_COND(!png_image_write_to_memory(&png_meta, png.ptrw(), &len, 0, data.ptr(), 0, nullptr)); - - godot_js_display_cursor_set_custom_shape(godot2dom_cursor(p_shape), png.ptr(), len, p_hotspot.x, p_hotspot.y); - - } else { - godot_js_display_cursor_set_custom_shape(godot2dom_cursor(p_shape), nullptr, 0, 0, 0); - } - - cursor_set_shape(cursor_shape); -} - -// Mouse mode -void DisplayServerJavaScript::mouse_set_mode(MouseMode p_mode) { - ERR_FAIL_COND_MSG(p_mode == MOUSE_MODE_CONFINED || p_mode == MOUSE_MODE_CONFINED_HIDDEN, "MOUSE_MODE_CONFINED is not supported for the HTML5 platform."); - if (p_mode == mouse_get_mode()) { - return; - } - - if (p_mode == MOUSE_MODE_VISIBLE) { - godot_js_display_cursor_set_visible(1); - godot_js_display_cursor_lock_set(0); - - } else if (p_mode == MOUSE_MODE_HIDDEN) { - godot_js_display_cursor_set_visible(0); - godot_js_display_cursor_lock_set(0); - - } else if (p_mode == MOUSE_MODE_CAPTURED) { - godot_js_display_cursor_set_visible(1); - godot_js_display_cursor_lock_set(1); - } -} - -DisplayServer::MouseMode DisplayServerJavaScript::mouse_get_mode() const { - if (godot_js_display_cursor_is_hidden()) { - return MOUSE_MODE_HIDDEN; - } - - if (godot_js_display_cursor_is_locked()) { - return MOUSE_MODE_CAPTURED; - } - return MOUSE_MODE_VISIBLE; -} - -Point2i DisplayServerJavaScript::mouse_get_position() const { - return Input::get_singleton()->get_mouse_position(); -} - -// Wheel -int DisplayServerJavaScript::mouse_wheel_callback(double p_delta_x, double p_delta_y) { - if (!godot_js_display_canvas_is_focused()) { - if (get_singleton()->cursor_inside_canvas) { - godot_js_display_canvas_focus(); - } else { - return false; - } - } - - Input *input = Input::get_singleton(); - Ref<InputEventMouseButton> ev; - ev.instantiate(); - ev->set_position(input->get_mouse_position()); - ev->set_global_position(ev->get_position()); - - ev->set_shift_pressed(input->is_key_pressed(Key::SHIFT)); - ev->set_alt_pressed(input->is_key_pressed(Key::ALT)); - ev->set_ctrl_pressed(input->is_key_pressed(Key::CTRL)); - ev->set_meta_pressed(input->is_key_pressed(Key::META)); - - if (p_delta_y < 0) { - ev->set_button_index(MouseButton::WHEEL_UP); - } else if (p_delta_y > 0) { - ev->set_button_index(MouseButton::WHEEL_DOWN); - } else if (p_delta_x > 0) { - ev->set_button_index(MouseButton::WHEEL_LEFT); - } else if (p_delta_x < 0) { - ev->set_button_index(MouseButton::WHEEL_RIGHT); - } else { - return false; - } - - // Different browsers give wildly different delta values, and we can't - // interpret deltaMode, so use default value for wheel events' factor. - - MouseButton button_flag = mouse_button_to_mask(ev->get_button_index()); - - ev->set_pressed(true); - ev->set_button_mask(input->get_mouse_button_mask() | button_flag); - input->parse_input_event(ev); - - Ref<InputEventMouseButton> release = ev->duplicate(); - release->set_pressed(false); - release->set_button_mask(MouseButton(input->get_mouse_button_mask() & ~button_flag)); - input->parse_input_event(release); - - return true; -} - -// Touch -void DisplayServerJavaScript::touch_callback(int p_type, int p_count) { - DisplayServerJavaScript *ds = get_singleton(); - - const JSTouchEvent &touch_event = ds->touch_event; - for (int i = 0; i < p_count; i++) { - Point2 point(touch_event.coords[i * 2], touch_event.coords[i * 2 + 1]); - if (p_type == 2) { - // touchmove - Ref<InputEventScreenDrag> ev; - ev.instantiate(); - ev->set_index(touch_event.identifier[i]); - ev->set_position(point); - - Point2 &prev = ds->touches[i]; - ev->set_relative(ev->get_position() - prev); - prev = ev->get_position(); - - Input::get_singleton()->parse_input_event(ev); - } else { - // touchstart/touchend - Ref<InputEventScreenTouch> ev; - - // Resume audio context after input in case autoplay was denied. - OS_JavaScript::get_singleton()->resume_audio(); - - ev.instantiate(); - ev->set_index(touch_event.identifier[i]); - ev->set_position(point); - ev->set_pressed(p_type == 0); - ds->touches[i] = point; - - Input::get_singleton()->parse_input_event(ev); - - // Make sure to flush all events so we can call restricted APIs inside the event. - Input::get_singleton()->flush_buffered_events(); - } - } -} - -bool DisplayServerJavaScript::screen_is_touchscreen(int p_screen) const { - return godot_js_display_touchscreen_is_available(); -} - -// Virtual Keyboard -void DisplayServerJavaScript::vk_input_text_callback(const char *p_text, int p_cursor) { - DisplayServerJavaScript *ds = DisplayServerJavaScript::get_singleton(); - if (!ds || ds->input_text_callback.is_null()) { - return; - } - // Call input_text - Variant event = String::utf8(p_text); - Variant *eventp = &event; - Variant ret; - Callable::CallError ce; - ds->input_text_callback.call((const Variant **)&eventp, 1, ret, ce); - // Insert key right to reach position. - Input *input = Input::get_singleton(); - Ref<InputEventKey> k; - for (int i = 0; i < p_cursor; i++) { - k.instantiate(); - k->set_pressed(true); - k->set_echo(false); - k->set_keycode(Key::RIGHT); - input->parse_input_event(k); - k.instantiate(); - k->set_pressed(false); - k->set_echo(false); - k->set_keycode(Key::RIGHT); - input->parse_input_event(k); - } -} - -void DisplayServerJavaScript::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, bool p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) { - godot_js_display_vk_show(p_existing_text.utf8().get_data(), p_multiline, p_cursor_start, p_cursor_end); -} - -void DisplayServerJavaScript::virtual_keyboard_hide() { - godot_js_display_vk_hide(); -} - -void DisplayServerJavaScript::window_blur_callback() { - Input::get_singleton()->release_pressed_events(); -} - -// Gamepad -void DisplayServerJavaScript::gamepad_callback(int p_index, int p_connected, const char *p_id, const char *p_guid) { - Input *input = Input::get_singleton(); - if (p_connected) { - input->joy_connection_changed(p_index, true, String::utf8(p_id), String::utf8(p_guid)); - } else { - input->joy_connection_changed(p_index, false, ""); - } -} - -void DisplayServerJavaScript::process_joypads() { - Input *input = Input::get_singleton(); - int32_t pads = godot_js_input_gamepad_sample_count(); - int32_t s_btns_num = 0; - int32_t s_axes_num = 0; - int32_t s_standard = 0; - float s_btns[16]; - float s_axes[10]; - for (int idx = 0; idx < pads; idx++) { - int err = godot_js_input_gamepad_sample_get(idx, s_btns, &s_btns_num, s_axes, &s_axes_num, &s_standard); - if (err) { - continue; - } - for (int b = 0; b < s_btns_num; b++) { - // Buttons 6 and 7 in the standard mapping need to be - // axis to be handled as JoyAxis::TRIGGER by Godot. - if (s_standard && (b == 6 || b == 7)) { - input->joy_axis(idx, (JoyAxis)b, s_btns[b]); - } else { - input->joy_button(idx, (JoyButton)b, s_btns[b]); - } - } - for (int a = 0; a < s_axes_num; a++) { - input->joy_axis(idx, (JoyAxis)a, s_axes[a]); - } - } -} - -Vector<String> DisplayServerJavaScript::get_rendering_drivers_func() { - Vector<String> drivers; -#ifdef GLES3_ENABLED - drivers.push_back("opengl3"); -#endif - return drivers; -} - -// Clipboard -void DisplayServerJavaScript::update_clipboard_callback(const char *p_text) { - get_singleton()->clipboard = String::utf8(p_text); -} - -void DisplayServerJavaScript::clipboard_set(const String &p_text) { - clipboard = p_text; - int err = godot_js_display_clipboard_set(p_text.utf8().get_data()); - ERR_FAIL_COND_MSG(err, "Clipboard API is not supported."); -} - -String DisplayServerJavaScript::clipboard_get() const { - godot_js_display_clipboard_get(update_clipboard_callback); - return clipboard; -} - -void DisplayServerJavaScript::send_window_event_callback(int p_notification) { - DisplayServerJavaScript *ds = get_singleton(); - if (!ds) { - return; - } - if (p_notification == DisplayServer::WINDOW_EVENT_MOUSE_ENTER || p_notification == DisplayServer::WINDOW_EVENT_MOUSE_EXIT) { - ds->cursor_inside_canvas = p_notification == DisplayServer::WINDOW_EVENT_MOUSE_ENTER; - } - if (!ds->window_event_callback.is_null()) { - Variant event = int(p_notification); - Variant *eventp = &event; - Variant ret; - Callable::CallError ce; - ds->window_event_callback.call((const Variant **)&eventp, 1, ret, ce); - } -} - -void DisplayServerJavaScript::set_icon(const Ref<Image> &p_icon) { - ERR_FAIL_COND(p_icon.is_null()); - Ref<Image> icon = p_icon; - if (icon->is_compressed()) { - icon = icon->duplicate(); - ERR_FAIL_COND(icon->decompress() != OK); - } - if (icon->get_format() != Image::FORMAT_RGBA8) { - if (icon == p_icon) { - icon = icon->duplicate(); - } - icon->convert(Image::FORMAT_RGBA8); - } - - png_image png_meta; - memset(&png_meta, 0, sizeof png_meta); - png_meta.version = PNG_IMAGE_VERSION; - png_meta.width = icon->get_width(); - png_meta.height = icon->get_height(); - png_meta.format = PNG_FORMAT_RGBA; - - PackedByteArray png; - size_t len; - PackedByteArray data = icon->get_data(); - ERR_FAIL_COND(!png_image_write_get_memory_size(png_meta, len, 0, data.ptr(), 0, nullptr)); - - png.resize(len); - ERR_FAIL_COND(!png_image_write_to_memory(&png_meta, png.ptrw(), &len, 0, data.ptr(), 0, nullptr)); - - godot_js_display_window_icon_set(png.ptr(), len); -} - -void DisplayServerJavaScript::_dispatch_input_event(const Ref<InputEvent> &p_event) { - Callable cb = get_singleton()->input_event_callback; - if (!cb.is_null()) { - Variant ev = p_event; - Variant *evp = &ev; - Variant ret; - Callable::CallError ce; - cb.call((const Variant **)&evp, 1, ret, ce); - } -} - -DisplayServer *DisplayServerJavaScript::create_func(const String &p_rendering_driver, WindowMode p_window_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Size2i &p_resolution, Error &r_error) { - return memnew(DisplayServerJavaScript(p_rendering_driver, p_window_mode, p_vsync_mode, p_flags, p_resolution, r_error)); -} - -DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_driver, WindowMode p_window_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Size2i &p_resolution, Error &r_error) { - r_error = OK; // Always succeeds for now. - - // Ensure the canvas ID. - godot_js_config_canvas_id_get(canvas_id, 256); - - // Handle contextmenu, webglcontextlost - godot_js_display_setup_canvas(p_resolution.x, p_resolution.y, (p_window_mode == WINDOW_MODE_FULLSCREEN || p_window_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN), OS::get_singleton()->is_hidpi_allowed() ? 1 : 0); - - // Check if it's windows. - swap_cancel_ok = godot_js_display_is_swap_ok_cancel() == 1; - - // Expose method for requesting quit. - godot_js_os_request_quit_cb(request_quit_callback); - -#ifdef GLES3_ENABLED - // TODO "vulkan" defaults to webgl2 for now. - bool wants_webgl2 = p_rendering_driver == "opengl3" || p_rendering_driver == "vulkan"; - bool webgl2_init_failed = wants_webgl2 && !godot_js_display_has_webgl(2); - if (wants_webgl2 && !webgl2_init_failed) { - EmscriptenWebGLContextAttributes attributes; - emscripten_webgl_init_context_attributes(&attributes); - //attributes.alpha = GLOBAL_GET("display/window/per_pixel_transparency/allowed"); - attributes.alpha = true; - attributes.antialias = false; - attributes.majorVersion = 2; - - webgl_ctx = emscripten_webgl_create_context(canvas_id, &attributes); - if (emscripten_webgl_make_context_current(webgl_ctx) != EMSCRIPTEN_RESULT_SUCCESS) { - webgl2_init_failed = true; - } else { - RasterizerGLES3::make_current(); - } - } - if (webgl2_init_failed) { - OS::get_singleton()->alert("Your browser does not seem to support WebGL2. Please update your browser version.", - "Unable to initialize video driver"); - } - if (!wants_webgl2 || webgl2_init_failed) { - RasterizerDummy::make_current(); - } -#else - RasterizerDummy::make_current(); -#endif - - // JS Input interface (js/libs/library_godot_input.js) - godot_js_input_mouse_button_cb(&DisplayServerJavaScript::mouse_button_callback); - godot_js_input_mouse_move_cb(&DisplayServerJavaScript::mouse_move_callback); - godot_js_input_mouse_wheel_cb(&DisplayServerJavaScript::mouse_wheel_callback); - godot_js_input_touch_cb(&DisplayServerJavaScript::touch_callback, touch_event.identifier, touch_event.coords); - godot_js_input_key_cb(&DisplayServerJavaScript::key_callback, key_event.code, key_event.key); - godot_js_input_paste_cb(update_clipboard_callback); - godot_js_input_drop_files_cb(drop_files_js_callback); - godot_js_input_gamepad_cb(&DisplayServerJavaScript::gamepad_callback); - - // JS Display interface (js/libs/library_godot_display.js) - godot_js_display_fullscreen_cb(&DisplayServerJavaScript::fullscreen_change_callback); - godot_js_display_window_blur_cb(&window_blur_callback); - godot_js_display_notification_cb(&send_window_event_callback, - WINDOW_EVENT_MOUSE_ENTER, - WINDOW_EVENT_MOUSE_EXIT, - WINDOW_EVENT_FOCUS_IN, - WINDOW_EVENT_FOCUS_OUT); - godot_js_display_vk_cb(&vk_input_text_callback); - - Input::get_singleton()->set_event_dispatch_function(_dispatch_input_event); -} - -DisplayServerJavaScript::~DisplayServerJavaScript() { -#ifdef GLES3_ENABLED - if (webgl_ctx) { - emscripten_webgl_commit_frame(); - emscripten_webgl_destroy_context(webgl_ctx); - } -#endif -} - -bool DisplayServerJavaScript::has_feature(Feature p_feature) const { - switch (p_feature) { - //case FEATURE_GLOBAL_MENU: - //case FEATURE_HIDPI: - //case FEATURE_IME: - case FEATURE_ICON: - case FEATURE_CLIPBOARD: - case FEATURE_CURSOR_SHAPE: - case FEATURE_CUSTOM_CURSOR_SHAPE: - case FEATURE_MOUSE: - case FEATURE_TOUCHSCREEN: - return true; - //case FEATURE_MOUSE_WARP: - //case FEATURE_NATIVE_DIALOG: - //case FEATURE_NATIVE_ICON: - //case FEATURE_WINDOW_TRANSPARENCY: - //case FEATURE_KEEP_SCREEN_ON: - //case FEATURE_ORIENTATION: - case FEATURE_VIRTUAL_KEYBOARD: - return godot_js_display_vk_available() != 0; - case FEATURE_TEXT_TO_SPEECH: - return godot_js_display_tts_available() != 0; - default: - return false; - } -} - -void DisplayServerJavaScript::register_javascript_driver() { - register_create_function("javascript", create_func, get_rendering_drivers_func); -} - -String DisplayServerJavaScript::get_name() const { - return "javascript"; -} - -int DisplayServerJavaScript::get_screen_count() const { - return 1; -} - -Point2i DisplayServerJavaScript::screen_get_position(int p_screen) const { - return Point2i(); // TODO offsetX/Y? -} - -Size2i DisplayServerJavaScript::screen_get_size(int p_screen) const { - int size[2]; - godot_js_display_screen_size_get(size, size + 1); - return Size2(size[0], size[1]); -} - -Rect2i DisplayServerJavaScript::screen_get_usable_rect(int p_screen) const { - int size[2]; - godot_js_display_window_size_get(size, size + 1); - return Rect2i(0, 0, size[0], size[1]); -} - -int DisplayServerJavaScript::screen_get_dpi(int p_screen) const { - return godot_js_display_screen_dpi_get(); -} - -float DisplayServerJavaScript::screen_get_scale(int p_screen) const { - return godot_js_display_pixel_ratio_get(); -} - -float DisplayServerJavaScript::screen_get_refresh_rate(int p_screen) const { - return SCREEN_REFRESH_RATE_FALLBACK; // Javascript doesn't have much of a need for the screen refresh rate, and there's no native way to do so. -} - -Vector<DisplayServer::WindowID> DisplayServerJavaScript::get_window_list() const { - Vector<WindowID> ret; - ret.push_back(MAIN_WINDOW_ID); - return ret; -} - -DisplayServerJavaScript::WindowID DisplayServerJavaScript::get_window_at_screen_position(const Point2i &p_position) const { - return MAIN_WINDOW_ID; -} - -void DisplayServerJavaScript::window_attach_instance_id(ObjectID p_instance, WindowID p_window) { - window_attached_instance_id = p_instance; -} - -ObjectID DisplayServerJavaScript::window_get_attached_instance_id(WindowID p_window) const { - return window_attached_instance_id; -} - -void DisplayServerJavaScript::window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window) { - // Not supported. -} - -void DisplayServerJavaScript::window_set_window_event_callback(const Callable &p_callable, WindowID p_window) { - window_event_callback = p_callable; -} - -void DisplayServerJavaScript::window_set_input_event_callback(const Callable &p_callable, WindowID p_window) { - input_event_callback = p_callable; -} - -void DisplayServerJavaScript::window_set_input_text_callback(const Callable &p_callable, WindowID p_window) { - input_text_callback = p_callable; -} - -void DisplayServerJavaScript::window_set_drop_files_callback(const Callable &p_callable, WindowID p_window) { - drop_files_callback = p_callable; -} - -void DisplayServerJavaScript::window_set_title(const String &p_title, WindowID p_window) { - godot_js_display_window_title_set(p_title.utf8().get_data()); -} - -int DisplayServerJavaScript::window_get_current_screen(WindowID p_window) const { - return 1; -} - -void DisplayServerJavaScript::window_set_current_screen(int p_screen, WindowID p_window) { - // Not implemented. -} - -Point2i DisplayServerJavaScript::window_get_position(WindowID p_window) const { - return Point2i(); // TODO Does this need implementation? -} - -void DisplayServerJavaScript::window_set_position(const Point2i &p_position, WindowID p_window) { - // Not supported. -} - -void DisplayServerJavaScript::window_set_transient(WindowID p_window, WindowID p_parent) { - // Not supported. -} - -void DisplayServerJavaScript::window_set_max_size(const Size2i p_size, WindowID p_window) { - // Not supported. -} - -Size2i DisplayServerJavaScript::window_get_max_size(WindowID p_window) const { - return Size2i(); -} - -void DisplayServerJavaScript::window_set_min_size(const Size2i p_size, WindowID p_window) { - // Not supported. -} - -Size2i DisplayServerJavaScript::window_get_min_size(WindowID p_window) const { - return Size2i(); -} - -void DisplayServerJavaScript::window_set_size(const Size2i p_size, WindowID p_window) { - godot_js_display_desired_size_set(p_size.x, p_size.y); -} - -Size2i DisplayServerJavaScript::window_get_size(WindowID p_window) const { - int size[2]; - godot_js_display_window_size_get(size, size + 1); - return Size2i(size[0], size[1]); -} - -Size2i DisplayServerJavaScript::window_get_real_size(WindowID p_window) const { - return window_get_size(p_window); -} - -void DisplayServerJavaScript::window_set_mode(WindowMode p_mode, WindowID p_window) { - if (window_mode == p_mode) { - return; - } - - switch (p_mode) { - case WINDOW_MODE_WINDOWED: { - if (window_mode == WINDOW_MODE_FULLSCREEN) { - godot_js_display_fullscreen_exit(); - } - window_mode = WINDOW_MODE_WINDOWED; - } break; - case WINDOW_MODE_EXCLUSIVE_FULLSCREEN: - case WINDOW_MODE_FULLSCREEN: { - int result = godot_js_display_fullscreen_request(); - ERR_FAIL_COND_MSG(result, "The request was denied. Remember that enabling fullscreen is only possible from an input callback for the HTML5 platform."); - } break; - case WINDOW_MODE_MAXIMIZED: - case WINDOW_MODE_MINIMIZED: - WARN_PRINT("WindowMode MAXIMIZED and MINIMIZED are not supported in HTML5 platform."); - break; - default: - break; - } -} - -DisplayServerJavaScript::WindowMode DisplayServerJavaScript::window_get_mode(WindowID p_window) const { - return window_mode; -} - -bool DisplayServerJavaScript::window_is_maximize_allowed(WindowID p_window) const { - return false; -} - -void DisplayServerJavaScript::window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window) { - // Not supported. -} - -bool DisplayServerJavaScript::window_get_flag(WindowFlags p_flag, WindowID p_window) const { - return false; -} - -void DisplayServerJavaScript::window_request_attention(WindowID p_window) { - // Not supported. -} - -void DisplayServerJavaScript::window_move_to_foreground(WindowID p_window) { - // Not supported. -} - -bool DisplayServerJavaScript::window_can_draw(WindowID p_window) const { - return true; -} - -bool DisplayServerJavaScript::can_any_window_draw() const { - return true; -} - -void DisplayServerJavaScript::process_events() { - Input::get_singleton()->flush_buffered_events(); - if (godot_js_input_gamepad_sample() == OK) { - process_joypads(); - } -} - -int DisplayServerJavaScript::get_current_video_driver() const { - return 1; -} - -bool DisplayServerJavaScript::get_swap_cancel_ok() { - return swap_cancel_ok; -} - -void DisplayServerJavaScript::swap_buffers() { -#ifdef GLES3_ENABLED - if (webgl_ctx) { - emscripten_webgl_commit_frame(); - } -#endif -} diff --git a/platform/javascript/display_server_javascript.h b/platform/javascript/display_server_javascript.h deleted file mode 100644 index 79b0fbb652..0000000000 --- a/platform/javascript/display_server_javascript.h +++ /dev/null @@ -1,228 +0,0 @@ -/*************************************************************************/ -/* display_server_javascript.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef DISPLAY_SERVER_JAVASCRIPT_H -#define DISPLAY_SERVER_JAVASCRIPT_H - -#include "servers/display_server.h" - -#include <emscripten.h> -#include <emscripten/html5.h> - -class DisplayServerJavaScript : public DisplayServer { -private: - struct JSTouchEvent { - uint32_t identifier[32] = { 0 }; - double coords[64] = { 0 }; - }; - JSTouchEvent touch_event; - - struct JSKeyEvent { - char code[32] = { 0 }; - char key[32] = { 0 }; - uint8_t modifiers[4] = { 0 }; - }; - JSKeyEvent key_event; - -#ifdef GLES3_ENABLED - EMSCRIPTEN_WEBGL_CONTEXT_HANDLE webgl_ctx = 0; -#endif - - HashMap<int, CharString> utterance_ids; - - WindowMode window_mode = WINDOW_MODE_WINDOWED; - ObjectID window_attached_instance_id = {}; - - Callable window_event_callback; - Callable input_event_callback; - Callable input_text_callback; - Callable drop_files_callback; - - String clipboard; - Point2 touches[32]; - - Array voices; - - char canvas_id[256] = { 0 }; - bool cursor_inside_canvas = true; - CursorShape cursor_shape = CURSOR_ARROW; - Point2i last_click_pos = Point2(-100, -100); // TODO check this again. - uint64_t last_click_ms = 0; - MouseButton last_click_button_index = MouseButton::NONE; - - bool swap_cancel_ok = false; - - // utilities - static void dom2godot_mod(Ref<InputEventWithModifiers> ev, int p_mod); - static const char *godot2dom_cursor(DisplayServer::CursorShape p_shape); - - // events - static void fullscreen_change_callback(int p_fullscreen); - static int mouse_button_callback(int p_pressed, int p_button, double p_x, double p_y, int p_modifiers); - static void mouse_move_callback(double p_x, double p_y, double p_rel_x, double p_rel_y, int p_modifiers); - static int mouse_wheel_callback(double p_delta_x, double p_delta_y); - static void touch_callback(int p_type, int p_count); - static void key_callback(int p_pressed, int p_repeat, int p_modifiers); - static void vk_input_text_callback(const char *p_text, int p_cursor); - static void gamepad_callback(int p_index, int p_connected, const char *p_id, const char *p_guid); - void process_joypads(); - static void _js_utterance_callback(int p_event, int p_id, int p_pos); - - static Vector<String> get_rendering_drivers_func(); - static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_window_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error); - - static void _dispatch_input_event(const Ref<InputEvent> &p_event); - - static void request_quit_callback(); - static void window_blur_callback(); - static void update_voices_callback(int p_size, const char **p_voice); - static void update_clipboard_callback(const char *p_text); - static void send_window_event_callback(int p_notification); - static void drop_files_js_callback(char **p_filev, int p_filec); - -protected: - int get_current_video_driver() const; - -public: - // Override return type to make writing static callbacks less tedious. - static DisplayServerJavaScript *get_singleton(); - - // utilities - bool check_size_force_redraw(); - - // from DisplayServer - virtual bool has_feature(Feature p_feature) const override; - virtual String get_name() const override; - - // tts - virtual bool tts_is_speaking() const override; - virtual bool tts_is_paused() const override; - virtual Array tts_get_voices() const override; - - virtual void tts_speak(const String &p_text, const String &p_voice, int p_volume = 50, float p_pitch = 1.f, float p_rate = 1.f, int p_utterance_id = 0, bool p_interrupt = false) override; - virtual void tts_pause() override; - virtual void tts_resume() override; - virtual void tts_stop() override; - - // cursor - virtual void cursor_set_shape(CursorShape p_shape) override; - virtual CursorShape cursor_get_shape() const override; - virtual void cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape = CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()) override; - - // mouse - virtual void mouse_set_mode(MouseMode p_mode) override; - virtual MouseMode mouse_get_mode() const override; - virtual Point2i mouse_get_position() const override; - - // touch - virtual bool screen_is_touchscreen(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; - - // clipboard - virtual void clipboard_set(const String &p_text) override; - virtual String clipboard_get() const override; - - // screen - virtual int get_screen_count() const override; - virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; - virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; - virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; - virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; - virtual float screen_get_scale(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; - virtual float screen_get_refresh_rate(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; - - virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), bool p_multiline = false, int p_max_input_length = -1, int p_cursor_start = -1, int p_cursor_end = -1) override; - virtual void virtual_keyboard_hide() override; - - // windows - virtual Vector<DisplayServer::WindowID> get_window_list() const override; - virtual WindowID get_window_at_screen_position(const Point2i &p_position) const override; - - virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID) override; - virtual ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const override; - - virtual void window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override; - - virtual void window_set_window_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override; - virtual void window_set_input_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override; - virtual void window_set_input_text_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override; - - virtual void window_set_drop_files_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override; - - virtual void window_set_title(const String &p_title, WindowID p_window = MAIN_WINDOW_ID) override; - - virtual int window_get_current_screen(WindowID p_window = MAIN_WINDOW_ID) const override; - virtual void window_set_current_screen(int p_screen, WindowID p_window = MAIN_WINDOW_ID) override; - - virtual Point2i window_get_position(WindowID p_window = MAIN_WINDOW_ID) const override; - virtual void window_set_position(const Point2i &p_position, WindowID p_window = MAIN_WINDOW_ID) override; - - virtual void window_set_transient(WindowID p_window, WindowID p_parent) override; - - virtual void window_set_max_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override; - virtual Size2i window_get_max_size(WindowID p_window = MAIN_WINDOW_ID) const override; - - virtual void window_set_min_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override; - virtual Size2i window_get_min_size(WindowID p_window = MAIN_WINDOW_ID) const override; - - virtual void window_set_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override; - virtual Size2i window_get_size(WindowID p_window = MAIN_WINDOW_ID) const override; - virtual Size2i window_get_real_size(WindowID p_window = MAIN_WINDOW_ID) const override; - - virtual void window_set_mode(WindowMode p_mode, WindowID p_window = MAIN_WINDOW_ID) override; - virtual WindowMode window_get_mode(WindowID p_window = MAIN_WINDOW_ID) const override; - - virtual bool window_is_maximize_allowed(WindowID p_window = MAIN_WINDOW_ID) const override; - - virtual void window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window = MAIN_WINDOW_ID) override; - virtual bool window_get_flag(WindowFlags p_flag, WindowID p_window = MAIN_WINDOW_ID) const override; - - virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override; - virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override; - - virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const override; - - virtual bool can_any_window_draw() const override; - - // events - virtual void process_events() override; - - // icon - virtual void set_icon(const Ref<Image> &p_icon) override; - - // others - virtual bool get_swap_cancel_ok() override; - virtual void swap_buffers() override; - - static void register_javascript_driver(); - DisplayServerJavaScript(const String &p_rendering_driver, WindowMode p_window_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Size2i &p_resolution, Error &r_error); - ~DisplayServerJavaScript(); -}; - -#endif // DISPLAY_SERVER_JAVASCRIPT_H diff --git a/platform/javascript/dom_keys.inc b/platform/javascript/dom_keys.inc deleted file mode 100644 index 115b5479e4..0000000000 --- a/platform/javascript/dom_keys.inc +++ /dev/null @@ -1,232 +0,0 @@ -/*************************************************************************/ -/* dom_keys.inc */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "core/os/keyboard.h" - -// See https://w3c.github.io/uievents-code/#code-value-tables -Key dom_code2godot_scancode(EM_UTF8 const p_code[32], EM_UTF8 const p_key[32], bool p_physical) { -#define DOM2GODOT(p_str, p_godot_code) \ - if (memcmp((const void *)p_str, (void *)p_code, strlen(p_str) + 1) == 0) { \ - return Key::p_godot_code; \ - } - - // Numpad section. - DOM2GODOT("NumLock", NUMLOCK); - DOM2GODOT("Numpad0", KP_0); - DOM2GODOT("Numpad1", KP_1); - DOM2GODOT("Numpad2", KP_2); - DOM2GODOT("Numpad3", KP_3); - DOM2GODOT("Numpad4", KP_4); - DOM2GODOT("Numpad5", KP_5); - DOM2GODOT("Numpad6", KP_6); - DOM2GODOT("Numpad7", KP_7); - DOM2GODOT("Numpad8", KP_8); - DOM2GODOT("Numpad9", KP_9); - DOM2GODOT("NumpadAdd", KP_ADD); - DOM2GODOT("NumpadBackspace", BACKSPACE); - DOM2GODOT("NumpadClear", CLEAR); - DOM2GODOT("NumpadClearEntry", CLEAR); - //DOM2GODOT("NumpadComma", UNKNOWN); - DOM2GODOT("NumpadDecimal", KP_PERIOD); - DOM2GODOT("NumpadDivide", KP_DIVIDE); - DOM2GODOT("NumpadEnter", KP_ENTER); - DOM2GODOT("NumpadEqual", EQUAL); - //DOM2GODOT("NumpadHash", UNKNOWN); - //DOM2GODOT("NumpadMemoryAdd", UNKNOWN); - //DOM2GODOT("NumpadMemoryClear", UNKNOWN); - //DOM2GODOT("NumpadMemoryRecall", UNKNOWN); - //DOM2GODOT("NumpadMemoryStore", UNKNOWN); - //DOM2GODOT("NumpadMemorySubtract", UNKNOWN); - DOM2GODOT("NumpadMultiply", KP_MULTIPLY); - DOM2GODOT("NumpadParenLeft", PARENLEFT); - DOM2GODOT("NumpadParenRight", PARENRIGHT); - DOM2GODOT("NumpadStar", KP_MULTIPLY); // or ASTERISK ? - DOM2GODOT("NumpadSubtract", KP_SUBTRACT); - - // Printable ASCII. - if (!p_physical) { - uint8_t b0 = (uint8_t)p_key[0]; - uint8_t b1 = (uint8_t)p_key[1]; - uint8_t b2 = (uint8_t)p_key[2]; - if (b1 == 0 && b0 > 0x1F && b0 < 0x7F) { // ASCII. - if (b0 > 0x60 && b0 < 0x7B) { // Lowercase ASCII. - b0 -= 32; - } - return (Key)b0; - } - -#define _U_2BYTES_MASK 0xE0 -#define _U_2BYTES 0xC0 - // Latin-1 codes. - if (b2 == 0 && (b0 & _U_2BYTES_MASK) == _U_2BYTES) { // 2-bytes utf8, only known latin. - uint32_t key = ((b0 & ~_U_2BYTES_MASK) << 6) | (b1 & 0x3F); - if (key >= 0xA0 && key <= 0xDF) { - return (Key)key; - } - if (key >= 0xE0 && key <= 0xFF) { // Lowercase known latin. - key -= 0x20; - return (Key)key; - } - } -#undef _U_2BYTES_MASK -#undef _U_2BYTES - } - - // Alphanumeric section. - DOM2GODOT("Backquote", QUOTELEFT); - DOM2GODOT("Backslash", BACKSLASH); - DOM2GODOT("BracketLeft", BRACKETLEFT); - DOM2GODOT("BracketRight", BRACKETRIGHT); - DOM2GODOT("Comma", COMMA); - DOM2GODOT("Digit0", KEY_0); - DOM2GODOT("Digit1", KEY_1); - DOM2GODOT("Digit2", KEY_2); - DOM2GODOT("Digit3", KEY_3); - DOM2GODOT("Digit4", KEY_4); - DOM2GODOT("Digit5", KEY_5); - DOM2GODOT("Digit6", KEY_6); - DOM2GODOT("Digit7", KEY_7); - DOM2GODOT("Digit8", KEY_8); - DOM2GODOT("Digit9", KEY_9); - DOM2GODOT("Equal", EQUAL); - DOM2GODOT("IntlBackslash", BACKSLASH); - //DOM2GODOT("IntlRo", UNKNOWN); - DOM2GODOT("IntlYen", YEN); - - DOM2GODOT("KeyA", A); - DOM2GODOT("KeyB", B); - DOM2GODOT("KeyC", C); - DOM2GODOT("KeyD", D); - DOM2GODOT("KeyE", E); - DOM2GODOT("KeyF", F); - DOM2GODOT("KeyG", G); - DOM2GODOT("KeyH", H); - DOM2GODOT("KeyI", I); - DOM2GODOT("KeyJ", J); - DOM2GODOT("KeyK", K); - DOM2GODOT("KeyL", L); - DOM2GODOT("KeyM", M); - DOM2GODOT("KeyN", N); - DOM2GODOT("KeyO", O); - DOM2GODOT("KeyP", P); - DOM2GODOT("KeyQ", Q); - DOM2GODOT("KeyR", R); - DOM2GODOT("KeyS", S); - DOM2GODOT("KeyT", T); - DOM2GODOT("KeyU", U); - DOM2GODOT("KeyV", V); - DOM2GODOT("KeyW", W); - DOM2GODOT("KeyX", X); - DOM2GODOT("KeyY", Y); - DOM2GODOT("KeyZ", Z); - - DOM2GODOT("Minus", MINUS); - DOM2GODOT("Period", PERIOD); - DOM2GODOT("Quote", APOSTROPHE); - DOM2GODOT("Semicolon", SEMICOLON); - DOM2GODOT("Slash", SLASH); - - // Functional keys in the Alphanumeric section. - DOM2GODOT("AltLeft", ALT); - DOM2GODOT("AltRight", ALT); - DOM2GODOT("Backspace", BACKSPACE); - DOM2GODOT("CapsLock", CAPSLOCK); - DOM2GODOT("ContextMenu", MENU); - DOM2GODOT("ControlLeft", CTRL); - DOM2GODOT("ControlRight", CTRL); - DOM2GODOT("Enter", ENTER); - DOM2GODOT("MetaLeft", SUPER_L); - DOM2GODOT("MetaRight", SUPER_R); - DOM2GODOT("ShiftLeft", SHIFT); - DOM2GODOT("ShiftRight", SHIFT); - DOM2GODOT("Space", SPACE); - DOM2GODOT("Tab", TAB); - - // ControlPad section. - DOM2GODOT("Delete", KEY_DELETE); - DOM2GODOT("End", END); - DOM2GODOT("Help", HELP); - DOM2GODOT("Home", HOME); - DOM2GODOT("Insert", INSERT); - DOM2GODOT("PageDown", PAGEDOWN); - DOM2GODOT("PageUp", PAGEUP); - - // ArrowPad section. - DOM2GODOT("ArrowDown", DOWN); - DOM2GODOT("ArrowLeft", LEFT); - DOM2GODOT("ArrowRight", RIGHT); - DOM2GODOT("ArrowUp", UP); - - // Function section. - DOM2GODOT("Escape", ESCAPE); - DOM2GODOT("F1", F1); - DOM2GODOT("F2", F2); - DOM2GODOT("F3", F3); - DOM2GODOT("F4", F4); - DOM2GODOT("F5", F5); - DOM2GODOT("F6", F6); - DOM2GODOT("F7", F7); - DOM2GODOT("F8", F8); - DOM2GODOT("F9", F9); - DOM2GODOT("F10", F10); - DOM2GODOT("F11", F11); - DOM2GODOT("F12", F12); - //DOM2GODOT("Fn", UNKNOWN); // never actually fired, but included in the standard draft. - //DOM2GODOT("FnLock", UNKNOWN); - DOM2GODOT("PrintScreen", PRINT); - DOM2GODOT("ScrollLock", SCROLLLOCK); - DOM2GODOT("Pause", PAUSE); - - // Media keys section. - DOM2GODOT("BrowserBack", BACK); - DOM2GODOT("BrowserFavorites", FAVORITES); - DOM2GODOT("BrowserForward", FORWARD); - DOM2GODOT("BrowserHome", OPENURL); - DOM2GODOT("BrowserRefresh", REFRESH); - DOM2GODOT("BrowserSearch", SEARCH); - DOM2GODOT("BrowserStop", STOP); - //DOM2GODOT("Eject", UNKNOWN); - DOM2GODOT("LaunchApp1", LAUNCH0); - DOM2GODOT("LaunchApp2", LAUNCH1); - DOM2GODOT("LaunchMail", LAUNCHMAIL); - DOM2GODOT("MediaPlayPause", MEDIAPLAY); - DOM2GODOT("MediaSelect", LAUNCHMEDIA); - DOM2GODOT("MediaStop", MEDIASTOP); - DOM2GODOT("MediaTrackNext", MEDIANEXT); - DOM2GODOT("MediaTrackPrevious", MEDIAPREVIOUS); - //DOM2GODOT("Power", UNKNOWN); - //DOM2GODOT("Sleep", UNKNOWN); - DOM2GODOT("AudioVolumeDown", VOLUMEDOWN); - DOM2GODOT("AudioVolumeMute", VOLUMEMUTE); - DOM2GODOT("AudioVolumeUp", VOLUMEUP); - //DOM2GODOT("WakeUp", UNKNOWN); - return Key::UNKNOWN; -#undef DOM2GODOT -} diff --git a/platform/javascript/emscripten_helpers.py b/platform/javascript/emscripten_helpers.py deleted file mode 100644 index 4dad2d5204..0000000000 --- a/platform/javascript/emscripten_helpers.py +++ /dev/null @@ -1,128 +0,0 @@ -import os, json - -from SCons.Util import WhereIs - - -def run_closure_compiler(target, source, env, for_signature): - closure_bin = os.path.join(os.path.dirname(WhereIs("emcc")), "node_modules", ".bin", "google-closure-compiler") - cmd = [WhereIs("node"), closure_bin] - cmd.extend(["--compilation_level", "ADVANCED_OPTIMIZATIONS"]) - for f in env["JSEXTERNS"]: - cmd.extend(["--externs", f.get_abspath()]) - for f in source: - cmd.extend(["--js", f.get_abspath()]) - cmd.extend(["--js_output_file", target[0].get_abspath()]) - return " ".join(cmd) - - -def get_build_version(): - import version - - name = "custom_build" - if os.getenv("BUILD_NAME") != None: - name = os.getenv("BUILD_NAME") - v = "%d.%d" % (version.major, version.minor) - if version.patch > 0: - v += ".%d" % version.patch - status = version.status - if os.getenv("GODOT_VERSION_STATUS") != None: - status = str(os.getenv("GODOT_VERSION_STATUS")) - v += ".%s.%s" % (status, name) - return v - - -def create_engine_file(env, target, source, externs): - if env["use_closure_compiler"]: - return env.BuildJS(target, source, JSEXTERNS=externs) - return env.Textfile(target, [env.File(s) for s in source]) - - -def create_template_zip(env, js, wasm, extra): - binary_name = "godot.tools" if env["tools"] else "godot" - zip_dir = env.Dir("#bin/.javascript_zip") - in_files = [ - js, - wasm, - "#platform/javascript/js/libs/audio.worklet.js", - ] - out_files = [ - zip_dir.File(binary_name + ".js"), - zip_dir.File(binary_name + ".wasm"), - zip_dir.File(binary_name + ".audio.worklet.js"), - ] - # GDNative/Threads specific - if env["gdnative_enabled"]: - in_files.append(extra) # Runtime - out_files.append(zip_dir.File(binary_name + ".side.wasm")) - elif env["threads_enabled"]: - in_files.append(extra) # Worker - out_files.append(zip_dir.File(binary_name + ".worker.js")) - - service_worker = "#misc/dist/html/service-worker.js" - if env["tools"]: - # HTML - html = "#misc/dist/html/editor.html" - cache = [ - "godot.tools.html", - "offline.html", - "godot.tools.js", - "godot.tools.worker.js", - "godot.tools.audio.worklet.js", - "logo.svg", - "favicon.png", - ] - opt_cache = ["godot.tools.wasm"] - subst_dict = { - "@GODOT_VERSION@": get_build_version(), - "@GODOT_NAME@": "GodotEngine", - "@GODOT_CACHE@": json.dumps(cache), - "@GODOT_OPT_CACHE@": json.dumps(opt_cache), - "@GODOT_OFFLINE_PAGE@": "offline.html", - } - html = env.Substfile(target="#bin/godot${PROGSUFFIX}.html", source=html, SUBST_DICT=subst_dict) - in_files.append(html) - out_files.append(zip_dir.File(binary_name + ".html")) - # And logo/favicon - in_files.append("#misc/dist/html/logo.svg") - out_files.append(zip_dir.File("logo.svg")) - in_files.append("#icon.png") - out_files.append(zip_dir.File("favicon.png")) - # PWA - service_worker = env.Substfile( - target="#bin/godot${PROGSUFFIX}.service.worker.js", source=service_worker, SUBST_DICT=subst_dict - ) - in_files.append(service_worker) - out_files.append(zip_dir.File("service.worker.js")) - in_files.append("#misc/dist/html/manifest.json") - out_files.append(zip_dir.File("manifest.json")) - in_files.append("#misc/dist/html/offline.html") - out_files.append(zip_dir.File("offline.html")) - else: - # HTML - in_files.append("#misc/dist/html/full-size.html") - out_files.append(zip_dir.File(binary_name + ".html")) - in_files.append(service_worker) - out_files.append(zip_dir.File(binary_name + ".service.worker.js")) - in_files.append("#misc/dist/html/offline-export.html") - out_files.append(zip_dir.File("godot.offline.html")) - - zip_files = env.InstallAs(out_files, in_files) - env.Zip( - "#bin/godot", - zip_files, - ZIPROOT=zip_dir, - ZIPSUFFIX="${PROGSUFFIX}${ZIPSUFFIX}", - ZIPCOMSTR="Archiving $SOURCES as $TARGET", - ) - - -def add_js_libraries(env, libraries): - env.Append(JS_LIBS=env.File(libraries)) - - -def add_js_pre(env, js_pre): - env.Append(JS_PRE=env.File(js_pre)) - - -def add_js_externs(env, externs): - env.Append(JS_EXTERNS=env.File(externs)) diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp deleted file mode 100644 index 825c1b6638..0000000000 --- a/platform/javascript/export/export.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************/ -/* export.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "export.h" - -#include "export_plugin.h" - -void register_javascript_exporter() { - EDITOR_DEF("export/web/http_host", "localhost"); - EDITOR_DEF("export/web/http_port", 8060); - EDITOR_DEF("export/web/use_ssl", false); - EDITOR_DEF("export/web/ssl_key", ""); - EDITOR_DEF("export/web/ssl_certificate", ""); - EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "export/web/http_port", PROPERTY_HINT_RANGE, "1,65535,1")); - EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/web/ssl_key", PROPERTY_HINT_GLOBAL_FILE, "*.key")); - EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/web/ssl_certificate", PROPERTY_HINT_GLOBAL_FILE, "*.crt,*.pem")); - - Ref<EditorExportPlatformJavaScript> platform; - platform.instantiate(); - EditorExport::get_singleton()->add_export_platform(platform); -} diff --git a/platform/javascript/export/export.h b/platform/javascript/export/export.h deleted file mode 100644 index 41cc66cfb8..0000000000 --- a/platform/javascript/export/export.h +++ /dev/null @@ -1,36 +0,0 @@ -/*************************************************************************/ -/* export.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef JAVASCRIPT_EXPORT_H -#define JAVASCRIPT_EXPORT_H - -void register_javascript_exporter(); - -#endif diff --git a/platform/javascript/export/export_plugin.cpp b/platform/javascript/export/export_plugin.cpp deleted file mode 100644 index 3334e7394b..0000000000 --- a/platform/javascript/export/export_plugin.cpp +++ /dev/null @@ -1,677 +0,0 @@ -/*************************************************************************/ -/* export_plugin.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "export_plugin.h" - -#include "core/config/project_settings.h" - -Error EditorExportPlatformJavaScript::_extract_template(const String &p_template, const String &p_dir, const String &p_name, bool pwa) { - Ref<FileAccess> io_fa; - zlib_filefunc_def io = zipio_create_io(&io_fa); - unzFile pkg = unzOpen2(p_template.utf8().get_data(), &io); - - if (!pkg) { - EditorNode::get_singleton()->show_warning(TTR("Could not open template for export:") + "\n" + p_template); - return ERR_FILE_NOT_FOUND; - } - - if (unzGoToFirstFile(pkg) != UNZ_OK) { - EditorNode::get_singleton()->show_warning(TTR("Invalid export template:") + "\n" + p_template); - unzClose(pkg); - return ERR_FILE_CORRUPT; - } - - do { - //get filename - unz_file_info info; - char fname[16384]; - unzGetCurrentFileInfo(pkg, &info, fname, 16384, nullptr, 0, nullptr, 0); - - String file = String::utf8(fname); - - // Skip service worker and offline page if not exporting pwa. - if (!pwa && (file == "godot.service.worker.js" || file == "godot.offline.html")) { - continue; - } - Vector<uint8_t> data; - data.resize(info.uncompressed_size); - - //read - unzOpenCurrentFile(pkg); - unzReadCurrentFile(pkg, data.ptrw(), data.size()); - unzCloseCurrentFile(pkg); - - //write - String dst = p_dir.plus_file(file.replace("godot", p_name)); - Ref<FileAccess> f = FileAccess::open(dst, FileAccess::WRITE); - if (f.is_null()) { - EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + dst); - unzClose(pkg); - return ERR_FILE_CANT_WRITE; - } - f->store_buffer(data.ptr(), data.size()); - - } while (unzGoToNextFile(pkg) == UNZ_OK); - unzClose(pkg); - return OK; -} - -Error EditorExportPlatformJavaScript::_write_or_error(const uint8_t *p_content, int p_size, String p_path) { - Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::WRITE); - if (f.is_null()) { - EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + p_path); - return ERR_FILE_CANT_WRITE; - } - f->store_buffer(p_content, p_size); - return OK; -} - -void EditorExportPlatformJavaScript::_replace_strings(HashMap<String, String> p_replaces, Vector<uint8_t> &r_template) { - String str_template = String::utf8(reinterpret_cast<const char *>(r_template.ptr()), r_template.size()); - String out; - Vector<String> lines = str_template.split("\n"); - for (int i = 0; i < lines.size(); i++) { - String current_line = lines[i]; - for (const KeyValue<String, String> &E : p_replaces) { - current_line = current_line.replace(E.key, E.value); - } - out += current_line + "\n"; - } - CharString cs = out.utf8(); - r_template.resize(cs.length()); - for (int i = 0; i < cs.length(); i++) { - r_template.write[i] = cs[i]; - } -} - -void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug, int p_flags, const Vector<SharedObject> p_shared_objects, const Dictionary &p_file_sizes) { - // Engine.js config - Dictionary config; - Array libs; - for (int i = 0; i < p_shared_objects.size(); i++) { - libs.push_back(p_shared_objects[i].path.get_file()); - } - Vector<String> flags; - gen_export_flags(flags, p_flags & (~DEBUG_FLAG_DUMB_CLIENT)); - Array args; - for (int i = 0; i < flags.size(); i++) { - args.push_back(flags[i]); - } - config["canvasResizePolicy"] = p_preset->get("html/canvas_resize_policy"); - config["experimentalVK"] = p_preset->get("html/experimental_virtual_keyboard"); - config["focusCanvas"] = p_preset->get("html/focus_canvas_on_start"); - config["gdnativeLibs"] = libs; - config["executable"] = p_name; - config["args"] = args; - config["fileSizes"] = p_file_sizes; - - String head_include; - if (p_preset->get("html/export_icon")) { - head_include += "<link id='-gd-engine-icon' rel='icon' type='image/png' href='" + p_name + ".icon.png' />\n"; - head_include += "<link rel='apple-touch-icon' href='" + p_name + ".apple-touch-icon.png'/>\n"; - } - if (p_preset->get("progressive_web_app/enabled")) { - head_include += "<link rel='manifest' href='" + p_name + ".manifest.json'>\n"; - config["serviceWorker"] = p_name + ".service.worker.js"; - } - - // Replaces HTML string - const String str_config = Variant(config).to_json_string(); - const String custom_head_include = p_preset->get("html/head_include"); - HashMap<String, String> replaces; - replaces["$GODOT_URL"] = p_name + ".js"; - replaces["$GODOT_PROJECT_NAME"] = ProjectSettings::get_singleton()->get_setting("application/config/name"); - replaces["$GODOT_HEAD_INCLUDE"] = head_include + custom_head_include; - replaces["$GODOT_CONFIG"] = str_config; - _replace_strings(replaces, p_html); -} - -Error EditorExportPlatformJavaScript::_add_manifest_icon(const String &p_path, const String &p_icon, int p_size, Array &r_arr) { - const String name = p_path.get_file().get_basename(); - const String icon_name = vformat("%s.%dx%d.png", name, p_size, p_size); - const String icon_dest = p_path.get_base_dir().plus_file(icon_name); - - Ref<Image> icon; - if (!p_icon.is_empty()) { - icon.instantiate(); - const Error err = ImageLoader::load_image(p_icon, icon); - if (err != OK) { - EditorNode::get_singleton()->show_warning(TTR("Could not read file:") + "\n" + p_icon); - return err; - } - if (icon->get_width() != p_size || icon->get_height() != p_size) { - icon->resize(p_size, p_size); - } - } else { - icon = _get_project_icon(); - icon->resize(p_size, p_size); - } - const Error err = icon->save_png(icon_dest); - if (err != OK) { - EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + icon_dest); - return err; - } - Dictionary icon_dict; - icon_dict["sizes"] = vformat("%dx%d", p_size, p_size); - icon_dict["type"] = "image/png"; - icon_dict["src"] = icon_name; - r_arr.push_back(icon_dict); - return err; -} - -Error EditorExportPlatformJavaScript::_build_pwa(const Ref<EditorExportPreset> &p_preset, const String p_path, const Vector<SharedObject> &p_shared_objects) { - String proj_name = ProjectSettings::get_singleton()->get_setting("application/config/name"); - if (proj_name.is_empty()) { - proj_name = "Godot Game"; - } - - // Service worker - const String dir = p_path.get_base_dir(); - const String name = p_path.get_file().get_basename(); - const ExportMode mode = (ExportMode)(int)p_preset->get("variant/export_type"); - HashMap<String, String> replaces; - replaces["@GODOT_VERSION@"] = String::num_int64(OS::get_singleton()->get_unix_time()) + "|" + String::num_int64(OS::get_singleton()->get_ticks_usec()); - replaces["@GODOT_NAME@"] = proj_name.substr(0, 16); - replaces["@GODOT_OFFLINE_PAGE@"] = name + ".offline.html"; - - // Files cached during worker install. - Array cache_files; - cache_files.push_back(name + ".html"); - cache_files.push_back(name + ".js"); - cache_files.push_back(name + ".offline.html"); - if (p_preset->get("html/export_icon")) { - cache_files.push_back(name + ".icon.png"); - cache_files.push_back(name + ".apple-touch-icon.png"); - } - if (mode == EXPORT_MODE_THREADS) { - cache_files.push_back(name + ".worker.js"); - cache_files.push_back(name + ".audio.worklet.js"); - } - replaces["@GODOT_CACHE@"] = Variant(cache_files).to_json_string(); - - // Heavy files that are cached on demand. - Array opt_cache_files; - opt_cache_files.push_back(name + ".wasm"); - opt_cache_files.push_back(name + ".pck"); - if (mode == EXPORT_MODE_GDNATIVE) { - opt_cache_files.push_back(name + ".side.wasm"); - for (int i = 0; i < p_shared_objects.size(); i++) { - opt_cache_files.push_back(p_shared_objects[i].path.get_file()); - } - } - replaces["@GODOT_OPT_CACHE@"] = Variant(opt_cache_files).to_json_string(); - - const String sw_path = dir.plus_file(name + ".service.worker.js"); - Vector<uint8_t> sw; - { - Ref<FileAccess> f = FileAccess::open(sw_path, FileAccess::READ); - if (f.is_null()) { - EditorNode::get_singleton()->show_warning(TTR("Could not read file:") + "\n" + sw_path); - return ERR_FILE_CANT_READ; - } - sw.resize(f->get_length()); - f->get_buffer(sw.ptrw(), sw.size()); - } - _replace_strings(replaces, sw); - Error err = _write_or_error(sw.ptr(), sw.size(), dir.plus_file(name + ".service.worker.js")); - if (err != OK) { - return err; - } - - // Custom offline page - const String offline_page = p_preset->get("progressive_web_app/offline_page"); - if (!offline_page.is_empty()) { - Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - const String offline_dest = dir.plus_file(name + ".offline.html"); - err = da->copy(ProjectSettings::get_singleton()->globalize_path(offline_page), offline_dest); - if (err != OK) { - EditorNode::get_singleton()->show_warning(TTR("Could not read file:") + "\n" + offline_dest); - return err; - } - } - - // Manifest - const char *modes[4] = { "fullscreen", "standalone", "minimal-ui", "browser" }; - const char *orientations[3] = { "any", "landscape", "portrait" }; - const int display = CLAMP(int(p_preset->get("progressive_web_app/display")), 0, 4); - const int orientation = CLAMP(int(p_preset->get("progressive_web_app/orientation")), 0, 3); - - Dictionary manifest; - manifest["name"] = proj_name; - manifest["start_url"] = "./" + name + ".html"; - manifest["display"] = String::utf8(modes[display]); - manifest["orientation"] = String::utf8(orientations[orientation]); - manifest["background_color"] = "#" + p_preset->get("progressive_web_app/background_color").operator Color().to_html(false); - - Array icons_arr; - const String icon144_path = p_preset->get("progressive_web_app/icon_144x144"); - err = _add_manifest_icon(p_path, icon144_path, 144, icons_arr); - if (err != OK) { - return err; - } - const String icon180_path = p_preset->get("progressive_web_app/icon_180x180"); - err = _add_manifest_icon(p_path, icon180_path, 180, icons_arr); - if (err != OK) { - return err; - } - const String icon512_path = p_preset->get("progressive_web_app/icon_512x512"); - err = _add_manifest_icon(p_path, icon512_path, 512, icons_arr); - if (err != OK) { - return err; - } - manifest["icons"] = icons_arr; - - CharString cs = Variant(manifest).to_json_string().utf8(); - err = _write_or_error((const uint8_t *)cs.get_data(), cs.length(), dir.plus_file(name + ".manifest.json")); - if (err != OK) { - return err; - } - - return OK; -} - -void EditorExportPlatformJavaScript::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) { - if (p_preset->get("vram_texture_compression/for_desktop")) { - r_features->push_back("s3tc"); - } - - if (p_preset->get("vram_texture_compression/for_mobile")) { - String driver = ProjectSettings::get_singleton()->get("rendering/driver/driver_name"); - if (driver == "opengl3") { - r_features->push_back("etc"); - } else if (driver == "vulkan") { - // FIXME: Review if this is correct. - r_features->push_back("etc2"); - } - } - ExportMode mode = (ExportMode)(int)p_preset->get("variant/export_type"); - if (mode == EXPORT_MODE_THREADS) { - r_features->push_back("threads"); - } else if (mode == EXPORT_MODE_GDNATIVE) { - r_features->push_back("wasm32"); - } -} - -void EditorExportPlatformJavaScript::get_export_options(List<ExportOption> *r_options) { - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), "")); - - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "variant/export_type", PROPERTY_HINT_ENUM, "Regular,Threads,GDNative"), 0)); // Export type. - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "vram_texture_compression/for_desktop"), true)); // S3TC - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "vram_texture_compression/for_mobile"), false)); // ETC or ETC2, depending on renderer - - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "html/export_icon"), true)); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "html/custom_html_shell", PROPERTY_HINT_FILE, "*.html"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "html/head_include", PROPERTY_HINT_MULTILINE_TEXT), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "html/canvas_resize_policy", PROPERTY_HINT_ENUM, "None,Project,Adaptive"), 2)); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "html/focus_canvas_on_start"), true)); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "html/experimental_virtual_keyboard"), false)); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "progressive_web_app/enabled"), false)); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "progressive_web_app/offline_page", PROPERTY_HINT_FILE, "*.html"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "progressive_web_app/display", PROPERTY_HINT_ENUM, "Fullscreen,Standalone,Minimal UI,Browser"), 1)); - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "progressive_web_app/orientation", PROPERTY_HINT_ENUM, "Any,Landscape,Portrait"), 0)); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "progressive_web_app/icon_144x144", PROPERTY_HINT_FILE, "*.png,*.webp,*.svg"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "progressive_web_app/icon_180x180", PROPERTY_HINT_FILE, "*.png,*.webp,*.svg"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "progressive_web_app/icon_512x512", PROPERTY_HINT_FILE, "*.png,*.webp,*.svg"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::COLOR, "progressive_web_app/background_color", PROPERTY_HINT_COLOR_NO_ALPHA), Color())); -} - -String EditorExportPlatformJavaScript::get_name() const { - return "HTML5"; -} - -String EditorExportPlatformJavaScript::get_os_name() const { - return "HTML5"; -} - -Ref<Texture2D> EditorExportPlatformJavaScript::get_logo() const { - return logo; -} - -bool EditorExportPlatformJavaScript::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const { -#ifndef DEV_ENABLED - // We don't provide export templates for the HTML5 platform currently as there - // is no suitable renderer to use with them. So we forbid exporting and tell - // users why. This is skipped in DEV_ENABLED so that contributors can still test - // the pipeline once we start having WebGL or WebGPU support. - r_error = "The HTML5 platform is currently not supported in Godot 4.0, as there is no suitable renderer for it.\n"; - return false; -#endif - - String err; - bool valid = false; - ExportMode mode = (ExportMode)(int)p_preset->get("variant/export_type"); - - // Look for export templates (first official, and if defined custom templates). - bool dvalid = exists_export_template(_get_template_name(mode, true), &err); - bool rvalid = exists_export_template(_get_template_name(mode, false), &err); - - if (p_preset->get("custom_template/debug") != "") { - dvalid = FileAccess::exists(p_preset->get("custom_template/debug")); - if (!dvalid) { - err += TTR("Custom debug template not found.") + "\n"; - } - } - if (p_preset->get("custom_template/release") != "") { - rvalid = FileAccess::exists(p_preset->get("custom_template/release")); - if (!rvalid) { - err += TTR("Custom release template not found.") + "\n"; - } - } - - valid = dvalid || rvalid; - r_missing_templates = !valid; - - // Validate the rest of the configuration. - - if (p_preset->get("vram_texture_compression/for_mobile")) { - String etc_error = test_etc2(); - if (!etc_error.is_empty()) { - valid = false; - err += etc_error; - } - } - - if (!err.is_empty()) { - r_error = err; - } - - return valid; -} - -List<String> EditorExportPlatformJavaScript::get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const { - List<String> list; - list.push_back("html"); - return list; -} - -Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { - ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags); - - const String custom_debug = p_preset->get("custom_template/debug"); - const String custom_release = p_preset->get("custom_template/release"); - const String custom_html = p_preset->get("html/custom_html_shell"); - const bool export_icon = p_preset->get("html/export_icon"); - const bool pwa = p_preset->get("progressive_web_app/enabled"); - - const String base_dir = p_path.get_base_dir(); - const String base_path = p_path.get_basename(); - const String base_name = p_path.get_file().get_basename(); - - // Find the correct template - String template_path = p_debug ? custom_debug : custom_release; - template_path = template_path.strip_edges(); - if (template_path.is_empty()) { - ExportMode mode = (ExportMode)(int)p_preset->get("variant/export_type"); - template_path = find_export_template(_get_template_name(mode, p_debug)); - } - - if (!DirAccess::exists(base_dir)) { - return ERR_FILE_BAD_PATH; - } - - if (!template_path.is_empty() && !FileAccess::exists(template_path)) { - EditorNode::get_singleton()->show_warning(TTR("Template file not found:") + "\n" + template_path); - return ERR_FILE_NOT_FOUND; - } - - // Export pck and shared objects - Vector<SharedObject> shared_objects; - String pck_path = base_path + ".pck"; - Error error = save_pack(p_preset, p_debug, pck_path, &shared_objects); - if (error != OK) { - EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + pck_path); - return error; - } - - { - Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - for (int i = 0; i < shared_objects.size(); i++) { - String dst = base_dir.plus_file(shared_objects[i].path.get_file()); - error = da->copy(shared_objects[i].path, dst); - if (error != OK) { - EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + shared_objects[i].path.get_file()); - return error; - } - } - } - - // Extract templates. - error = _extract_template(template_path, base_dir, base_name, pwa); - if (error) { - return error; - } - - // Parse generated file sizes (pck and wasm, to help show a meaningful loading bar). - Dictionary file_sizes; - Ref<FileAccess> f = FileAccess::open(pck_path, FileAccess::READ); - if (f.is_valid()) { - file_sizes[pck_path.get_file()] = (uint64_t)f->get_length(); - } - f = FileAccess::open(base_path + ".wasm", FileAccess::READ); - if (f.is_valid()) { - file_sizes[base_name + ".wasm"] = (uint64_t)f->get_length(); - } - - // Read the HTML shell file (custom or from template). - const String html_path = custom_html.is_empty() ? base_path + ".html" : custom_html; - Vector<uint8_t> html; - f = FileAccess::open(html_path, FileAccess::READ); - if (f.is_null()) { - EditorNode::get_singleton()->show_warning(TTR("Could not read HTML shell:") + "\n" + html_path); - return ERR_FILE_CANT_READ; - } - html.resize(f->get_length()); - f->get_buffer(html.ptrw(), html.size()); - - // Generate HTML file with replaced strings. - _fix_html(html, p_preset, base_name, p_debug, p_flags, shared_objects, file_sizes); - Error err = _write_or_error(html.ptr(), html.size(), p_path); - if (err != OK) { - return err; - } - html.resize(0); - - // Export splash (why?) - Ref<Image> splash = _get_project_splash(); - const String splash_png_path = base_path + ".png"; - if (splash->save_png(splash_png_path) != OK) { - EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + splash_png_path); - return ERR_FILE_CANT_WRITE; - } - - // Save a favicon that can be accessed without waiting for the project to finish loading. - // This way, the favicon can be displayed immediately when loading the page. - if (export_icon) { - Ref<Image> favicon = _get_project_icon(); - const String favicon_png_path = base_path + ".icon.png"; - if (favicon->save_png(favicon_png_path) != OK) { - EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + favicon_png_path); - return ERR_FILE_CANT_WRITE; - } - favicon->resize(180, 180); - const String apple_icon_png_path = base_path + ".apple-touch-icon.png"; - if (favicon->save_png(apple_icon_png_path) != OK) { - EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + apple_icon_png_path); - return ERR_FILE_CANT_WRITE; - } - } - - // Generate the PWA worker and manifest - if (pwa) { - err = _build_pwa(p_preset, p_path, shared_objects); - if (err != OK) { - return err; - } - } - - return OK; -} - -bool EditorExportPlatformJavaScript::poll_export() { - Ref<EditorExportPreset> preset; - - for (int i = 0; i < EditorExport::get_singleton()->get_export_preset_count(); i++) { - Ref<EditorExportPreset> ep = EditorExport::get_singleton()->get_export_preset(i); - if (ep->is_runnable() && ep->get_platform() == this) { - preset = ep; - break; - } - } - - int prev = menu_options; - menu_options = preset.is_valid(); - if (server->is_listening()) { - if (menu_options == 0) { - MutexLock lock(server_lock); - server->stop(); - } else { - menu_options += 1; - } - } - return menu_options != prev; -} - -Ref<ImageTexture> EditorExportPlatformJavaScript::get_option_icon(int p_index) const { - return p_index == 1 ? stop_icon : EditorExportPlatform::get_option_icon(p_index); -} - -int EditorExportPlatformJavaScript::get_options_count() const { - return menu_options; -} - -Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_preset, int p_option, int p_debug_flags) { - if (p_option == 1) { - MutexLock lock(server_lock); - server->stop(); - return OK; - } - - const String dest = EditorPaths::get_singleton()->get_cache_dir().plus_file("web"); - Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - if (!da->dir_exists(dest)) { - Error err = da->make_dir_recursive(dest); - if (err != OK) { - EditorNode::get_singleton()->show_warning(TTR("Could not create HTTP server directory:") + "\n" + dest); - return err; - } - } - const String basepath = dest.plus_file("tmp_js_export"); - Error err = export_project(p_preset, true, basepath + ".html", p_debug_flags); - if (err != OK) { - // Export generates several files, clean them up on failure. - DirAccess::remove_file_or_error(basepath + ".html"); - DirAccess::remove_file_or_error(basepath + ".offline.html"); - DirAccess::remove_file_or_error(basepath + ".js"); - DirAccess::remove_file_or_error(basepath + ".worker.js"); - DirAccess::remove_file_or_error(basepath + ".audio.worklet.js"); - DirAccess::remove_file_or_error(basepath + ".service.worker.js"); - DirAccess::remove_file_or_error(basepath + ".pck"); - DirAccess::remove_file_or_error(basepath + ".png"); - DirAccess::remove_file_or_error(basepath + ".side.wasm"); - DirAccess::remove_file_or_error(basepath + ".wasm"); - DirAccess::remove_file_or_error(basepath + ".icon.png"); - DirAccess::remove_file_or_error(basepath + ".apple-touch-icon.png"); - return err; - } - - const uint16_t bind_port = EDITOR_GET("export/web/http_port"); - // Resolve host if needed. - const String bind_host = EDITOR_GET("export/web/http_host"); - IPAddress bind_ip; - if (bind_host.is_valid_ip_address()) { - bind_ip = bind_host; - } else { - bind_ip = IP::get_singleton()->resolve_hostname(bind_host); - } - ERR_FAIL_COND_V_MSG(!bind_ip.is_valid(), ERR_INVALID_PARAMETER, "Invalid editor setting 'export/web/http_host': '" + bind_host + "'. Try using '127.0.0.1'."); - - const bool use_ssl = EDITOR_GET("export/web/use_ssl"); - const String ssl_key = EDITOR_GET("export/web/ssl_key"); - const String ssl_cert = EDITOR_GET("export/web/ssl_certificate"); - - // Restart server. - { - MutexLock lock(server_lock); - - server->stop(); - err = server->listen(bind_port, bind_ip, use_ssl, ssl_key, ssl_cert); - } - if (err != OK) { - EditorNode::get_singleton()->show_warning(TTR("Error starting HTTP server:") + "\n" + itos(err)); - return err; - } - - OS::get_singleton()->shell_open(String((use_ssl ? "https://" : "http://") + bind_host + ":" + itos(bind_port) + "/tmp_js_export.html")); - // FIXME: Find out how to clean up export files after running the successfully - // exported game. Might not be trivial. - return OK; -} - -Ref<Texture2D> EditorExportPlatformJavaScript::get_run_icon() const { - return run_icon; -} - -void EditorExportPlatformJavaScript::_server_thread_poll(void *data) { - EditorExportPlatformJavaScript *ej = static_cast<EditorExportPlatformJavaScript *>(data); - while (!ej->server_quit) { - OS::get_singleton()->delay_usec(6900); - { - MutexLock lock(ej->server_lock); - ej->server->poll(); - } - } -} - -EditorExportPlatformJavaScript::EditorExportPlatformJavaScript() { - server.instantiate(); - server_thread.start(_server_thread_poll, this); - - Ref<Image> img = memnew(Image(_javascript_logo)); - logo.instantiate(); - logo->create_from_image(img); - - img = Ref<Image>(memnew(Image(_javascript_run_icon))); - run_icon.instantiate(); - run_icon->create_from_image(img); - - Ref<Theme> theme = EditorNode::get_singleton()->get_editor_theme(); - if (theme.is_valid()) { - stop_icon = theme->get_icon(SNAME("Stop"), SNAME("EditorIcons")); - } else { - stop_icon.instantiate(); - } -} - -EditorExportPlatformJavaScript::~EditorExportPlatformJavaScript() { - server->stop(); - server_quit = true; - server_thread.wait_to_finish(); -} diff --git a/platform/javascript/export/export_plugin.h b/platform/javascript/export/export_plugin.h deleted file mode 100644 index d38d6e7073..0000000000 --- a/platform/javascript/export/export_plugin.h +++ /dev/null @@ -1,150 +0,0 @@ -/*************************************************************************/ -/* export_plugin.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef JAVASCRIPT_EXPORT_PLUGIN_H -#define JAVASCRIPT_EXPORT_PLUGIN_H - -#include "core/config/project_settings.h" -#include "core/io/image_loader.h" -#include "core/io/stream_peer_ssl.h" -#include "core/io/tcp_server.h" -#include "core/io/zip_io.h" -#include "editor/editor_export.h" -#include "editor/editor_node.h" -#include "main/splash.gen.h" -#include "platform/javascript/logo.gen.h" -#include "platform/javascript/run_icon.gen.h" - -#include "export_server.h" - -class EditorExportPlatformJavaScript : public EditorExportPlatform { - GDCLASS(EditorExportPlatformJavaScript, EditorExportPlatform); - - Ref<ImageTexture> logo; - Ref<ImageTexture> run_icon; - Ref<ImageTexture> stop_icon; - int menu_options = 0; - - Ref<EditorHTTPServer> server; - bool server_quit = false; - Mutex server_lock; - Thread server_thread; - - enum ExportMode { - EXPORT_MODE_NORMAL = 0, - EXPORT_MODE_THREADS = 1, - EXPORT_MODE_GDNATIVE = 2, - }; - - String _get_template_name(ExportMode p_mode, bool p_debug) const { - String name = "webassembly"; - switch (p_mode) { - case EXPORT_MODE_THREADS: - name += "_threads"; - break; - case EXPORT_MODE_GDNATIVE: - name += "_gdnative"; - break; - default: - break; - } - if (p_debug) { - name += "_debug.zip"; - } else { - name += "_release.zip"; - } - return name; - } - - Ref<Image> _get_project_icon() const { - Ref<Image> icon; - icon.instantiate(); - const String icon_path = String(GLOBAL_GET("application/config/icon")).strip_edges(); - if (icon_path.is_empty() || ImageLoader::load_image(icon_path, icon) != OK) { - return EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("DefaultProjectIcon"), SNAME("EditorIcons"))->get_image(); - } - return icon; - } - - Ref<Image> _get_project_splash() const { - Ref<Image> splash; - splash.instantiate(); - const String splash_path = String(GLOBAL_GET("application/boot_splash/image")).strip_edges(); - if (splash_path.is_empty() || ImageLoader::load_image(splash_path, splash) != OK) { - return Ref<Image>(memnew(Image(boot_splash_png))); - } - return splash; - } - - Error _extract_template(const String &p_template, const String &p_dir, const String &p_name, bool pwa); - void _replace_strings(HashMap<String, String> p_replaces, Vector<uint8_t> &r_template); - void _fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug, int p_flags, const Vector<SharedObject> p_shared_objects, const Dictionary &p_file_sizes); - Error _add_manifest_icon(const String &p_path, const String &p_icon, int p_size, Array &r_arr); - Error _build_pwa(const Ref<EditorExportPreset> &p_preset, const String p_path, const Vector<SharedObject> &p_shared_objects); - Error _write_or_error(const uint8_t *p_content, int p_len, String p_path); - - static void _server_thread_poll(void *data); - -public: - virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) override; - - virtual void get_export_options(List<ExportOption> *r_options) override; - - virtual String get_name() const override; - virtual String get_os_name() const override; - virtual Ref<Texture2D> get_logo() const override; - - virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const override; - virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const override; - virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override; - - virtual bool poll_export() override; - virtual int get_options_count() const override; - virtual String get_option_label(int p_index) const override { return p_index ? TTR("Stop HTTP Server") : TTR("Run in Browser"); } - virtual String get_option_tooltip(int p_index) const override { return p_index ? TTR("Stop HTTP Server") : TTR("Run exported HTML in the system's default browser."); } - virtual Ref<ImageTexture> get_option_icon(int p_index) const override; - virtual Error run(const Ref<EditorExportPreset> &p_preset, int p_option, int p_debug_flags) override; - virtual Ref<Texture2D> get_run_icon() const override; - - virtual void get_platform_features(List<String> *r_features) override { - r_features->push_back("web"); - r_features->push_back(get_os_name().to_lower()); - } - - virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, RBSet<String> &p_features) override { - } - - String get_debug_protocol() const override { return "ws://"; } - - EditorExportPlatformJavaScript(); - ~EditorExportPlatformJavaScript(); -}; - -#endif diff --git a/platform/javascript/export/export_server.h b/platform/javascript/export/export_server.h deleted file mode 100644 index a831b76076..0000000000 --- a/platform/javascript/export/export_server.h +++ /dev/null @@ -1,251 +0,0 @@ -/*************************************************************************/ -/* export_server.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef JAVASCRIPT_EXPORT_SERVER_H -#define JAVASCRIPT_EXPORT_SERVER_H - -#include "core/io/image_loader.h" -#include "core/io/stream_peer_ssl.h" -#include "core/io/tcp_server.h" -#include "core/io/zip_io.h" -#include "editor/editor_export.h" -#include "editor/editor_paths.h" - -class EditorHTTPServer : public RefCounted { -private: - Ref<TCPServer> server; - HashMap<String, String> mimes; - Ref<StreamPeerTCP> tcp; - Ref<StreamPeerSSL> ssl; - Ref<StreamPeer> peer; - Ref<CryptoKey> key; - Ref<X509Certificate> cert; - bool use_ssl = false; - uint64_t time = 0; - uint8_t req_buf[4096]; - int req_pos = 0; - - void _clear_client() { - peer = Ref<StreamPeer>(); - ssl = Ref<StreamPeerSSL>(); - tcp = Ref<StreamPeerTCP>(); - memset(req_buf, 0, sizeof(req_buf)); - time = 0; - req_pos = 0; - } - - void _set_internal_certs(Ref<Crypto> p_crypto) { - const String cache_path = EditorPaths::get_singleton()->get_cache_dir(); - const String key_path = cache_path.plus_file("html5_server.key"); - const String crt_path = cache_path.plus_file("html5_server.crt"); - bool regen = !FileAccess::exists(key_path) || !FileAccess::exists(crt_path); - if (!regen) { - key = Ref<CryptoKey>(CryptoKey::create()); - cert = Ref<X509Certificate>(X509Certificate::create()); - if (key->load(key_path) != OK || cert->load(crt_path) != OK) { - regen = true; - } - } - if (regen) { - key = p_crypto->generate_rsa(2048); - key->save(key_path); - cert = p_crypto->generate_self_signed_certificate(key, "CN=godot-debug.local,O=A Game Dev,C=XXA", "20140101000000", "20340101000000"); - cert->save(crt_path); - } - } - -public: - EditorHTTPServer() { - mimes["html"] = "text/html"; - mimes["js"] = "application/javascript"; - mimes["json"] = "application/json"; - mimes["pck"] = "application/octet-stream"; - mimes["png"] = "image/png"; - mimes["svg"] = "image/svg"; - mimes["wasm"] = "application/wasm"; - server.instantiate(); - stop(); - } - - void stop() { - server->stop(); - _clear_client(); - } - - Error listen(int p_port, IPAddress p_address, bool p_use_ssl, String p_ssl_key, String p_ssl_cert) { - use_ssl = p_use_ssl; - if (use_ssl) { - Ref<Crypto> crypto = Crypto::create(); - if (crypto.is_null()) { - return ERR_UNAVAILABLE; - } - if (!p_ssl_key.is_empty() && !p_ssl_cert.is_empty()) { - key = Ref<CryptoKey>(CryptoKey::create()); - Error err = key->load(p_ssl_key); - ERR_FAIL_COND_V(err != OK, err); - cert = Ref<X509Certificate>(X509Certificate::create()); - err = cert->load(p_ssl_cert); - ERR_FAIL_COND_V(err != OK, err); - } else { - _set_internal_certs(crypto); - } - } - return server->listen(p_port, p_address); - } - - bool is_listening() const { - return server->is_listening(); - } - - void _send_response() { - Vector<String> psa = String((char *)req_buf).split("\r\n"); - int len = psa.size(); - ERR_FAIL_COND_MSG(len < 4, "Not enough response headers, got: " + itos(len) + ", expected >= 4."); - - Vector<String> req = psa[0].split(" ", false); - ERR_FAIL_COND_MSG(req.size() < 2, "Invalid protocol or status code."); - - // Wrong protocol - ERR_FAIL_COND_MSG(req[0] != "GET" || req[2] != "HTTP/1.1", "Invalid method or HTTP version."); - - const int query_index = req[1].find_char('?'); - const String path = (query_index == -1) ? req[1] : req[1].substr(0, query_index); - - const String req_file = path.get_file(); - const String req_ext = path.get_extension(); - const String cache_path = EditorPaths::get_singleton()->get_cache_dir().plus_file("web"); - const String filepath = cache_path.plus_file(req_file); - - if (!mimes.has(req_ext) || !FileAccess::exists(filepath)) { - String s = "HTTP/1.1 404 Not Found\r\n"; - s += "Connection: Close\r\n"; - s += "\r\n"; - CharString cs = s.utf8(); - peer->put_data((const uint8_t *)cs.get_data(), cs.size() - 1); - return; - } - const String ctype = mimes[req_ext]; - - Ref<FileAccess> f = FileAccess::open(filepath, FileAccess::READ); - ERR_FAIL_COND(f.is_null()); - String s = "HTTP/1.1 200 OK\r\n"; - s += "Connection: Close\r\n"; - s += "Content-Type: " + ctype + "\r\n"; - s += "Access-Control-Allow-Origin: *\r\n"; - s += "Cross-Origin-Opener-Policy: same-origin\r\n"; - s += "Cross-Origin-Embedder-Policy: require-corp\r\n"; - s += "Cache-Control: no-store, max-age=0\r\n"; - s += "\r\n"; - CharString cs = s.utf8(); - Error err = peer->put_data((const uint8_t *)cs.get_data(), cs.size() - 1); - if (err != OK) { - ERR_FAIL(); - } - - while (true) { - uint8_t bytes[4096]; - uint64_t read = f->get_buffer(bytes, 4096); - if (read == 0) { - break; - } - err = peer->put_data(bytes, read); - if (err != OK) { - ERR_FAIL(); - } - } - } - - void poll() { - if (!server->is_listening()) { - return; - } - if (tcp.is_null()) { - if (!server->is_connection_available()) { - return; - } - tcp = server->take_connection(); - peer = tcp; - time = OS::get_singleton()->get_ticks_usec(); - } - if (OS::get_singleton()->get_ticks_usec() - time > 1000000) { - _clear_client(); - return; - } - if (tcp->get_status() != StreamPeerTCP::STATUS_CONNECTED) { - return; - } - - if (use_ssl) { - if (ssl.is_null()) { - ssl = Ref<StreamPeerSSL>(StreamPeerSSL::create()); - peer = ssl; - ssl->set_blocking_handshake_enabled(false); - if (ssl->accept_stream(tcp, key, cert) != OK) { - _clear_client(); - return; - } - } - ssl->poll(); - if (ssl->get_status() == StreamPeerSSL::STATUS_HANDSHAKING) { - // Still handshaking, keep waiting. - return; - } - if (ssl->get_status() != StreamPeerSSL::STATUS_CONNECTED) { - _clear_client(); - return; - } - } - - while (true) { - char *r = (char *)req_buf; - int l = req_pos - 1; - if (l > 3 && r[l] == '\n' && r[l - 1] == '\r' && r[l - 2] == '\n' && r[l - 3] == '\r') { - _send_response(); - _clear_client(); - return; - } - - int read = 0; - ERR_FAIL_COND(req_pos >= 4096); - Error err = peer->get_partial_data(&req_buf[req_pos], 1, read); - if (err != OK) { - // Got an error - _clear_client(); - return; - } else if (read != 1) { - // Busy, wait next poll - return; - } - req_pos += read; - } - } -}; - -#endif diff --git a/platform/javascript/godot_audio.h b/platform/javascript/godot_audio.h deleted file mode 100644 index 012f8daeb7..0000000000 --- a/platform/javascript/godot_audio.h +++ /dev/null @@ -1,66 +0,0 @@ -/*************************************************************************/ -/* godot_audio.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef GODOT_AUDIO_H -#define GODOT_AUDIO_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "stddef.h" - -extern int godot_audio_is_available(); -extern int godot_audio_has_worklet(); -extern int godot_audio_has_script_processor(); -extern int godot_audio_init(int *p_mix_rate, int p_latency, void (*_state_cb)(int), void (*_latency_cb)(float)); -extern void godot_audio_resume(); - -extern int godot_audio_capture_start(); -extern void godot_audio_capture_stop(); - -// Worklet -typedef int32_t GodotAudioState[4]; -extern int godot_audio_worklet_create(int p_channels); -extern void godot_audio_worklet_start(float *p_in_buf, int p_in_size, float *p_out_buf, int p_out_size, GodotAudioState p_state); -extern void godot_audio_worklet_start_no_threads(float *p_out_buf, int p_out_size, void (*p_out_cb)(int p_pos, int p_frames), float *p_in_buf, int p_in_size, void (*p_in_cb)(int p_pos, int p_frames)); -extern int godot_audio_worklet_state_add(GodotAudioState p_state, int p_idx, int p_value); -extern int godot_audio_worklet_state_get(GodotAudioState p_state, int p_idx); -extern int godot_audio_worklet_state_wait(int32_t *p_state, int p_idx, int32_t p_expected, int p_timeout); - -// Script -extern int godot_audio_script_create(int *p_buffer_size, int p_channels); -extern void godot_audio_script_start(float *p_in_buf, int p_in_size, float *p_out_buf, int p_out_size, void (*p_cb)()); - -#ifdef __cplusplus -} -#endif - -#endif /* GODOT_AUDIO_H */ diff --git a/platform/javascript/godot_js.h b/platform/javascript/godot_js.h deleted file mode 100644 index 1a383c9799..0000000000 --- a/platform/javascript/godot_js.h +++ /dev/null @@ -1,130 +0,0 @@ -/*************************************************************************/ -/* godot_js.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef GODOT_JS_H -#define GODOT_JS_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "stddef.h" - -// Config -extern void godot_js_config_locale_get(char *p_ptr, int p_ptr_max); -extern void godot_js_config_canvas_id_get(char *p_ptr, int p_ptr_max); - -// OS -extern void godot_js_os_finish_async(void (*p_callback)()); -extern void godot_js_os_request_quit_cb(void (*p_callback)()); -extern int godot_js_os_fs_is_persistent(); -extern void godot_js_os_fs_sync(void (*p_callback)()); -extern int godot_js_os_execute(const char *p_json); -extern void godot_js_os_shell_open(const char *p_uri); -extern int godot_js_os_hw_concurrency_get(); -extern int godot_js_pwa_cb(void (*p_callback)()); -extern int godot_js_pwa_update(); - -// Input -extern void godot_js_input_mouse_button_cb(int (*p_callback)(int p_pressed, int p_button, double p_x, double p_y, int p_modifiers)); -extern void godot_js_input_mouse_move_cb(void (*p_callback)(double p_x, double p_y, double p_rel_x, double p_rel_y, int p_modifiers)); -extern void godot_js_input_mouse_wheel_cb(int (*p_callback)(double p_delta_x, double p_delta_y)); -extern void godot_js_input_touch_cb(void (*p_callback)(int p_type, int p_count), uint32_t *r_identifiers, double *r_coords); -extern void godot_js_input_key_cb(void (*p_callback)(int p_type, int p_repeat, int p_modifiers), char r_code[32], char r_key[32]); - -// Input gamepad -extern void godot_js_input_gamepad_cb(void (*p_on_change)(int p_index, int p_connected, const char *p_id, const char *p_guid)); -extern int godot_js_input_gamepad_sample(); -extern int godot_js_input_gamepad_sample_count(); -extern int godot_js_input_gamepad_sample_get(int p_idx, float r_btns[16], int32_t *r_btns_num, float r_axes[10], int32_t *r_axes_num, int32_t *r_standard); -extern void godot_js_input_paste_cb(void (*p_callback)(const char *p_text)); -extern void godot_js_input_drop_files_cb(void (*p_callback)(char **p_filev, int p_filec)); - -// TTS -extern int godot_js_tts_is_speaking(); -extern int godot_js_tts_is_paused(); -extern int godot_js_tts_get_voices(void (*p_callback)(int p_size, const char **p_voices)); -extern void godot_js_tts_speak(const char *p_text, const char *p_voice, int p_volume, float p_pitch, float p_rate, int p_utterance_id, void (*p_callback)(int p_event, int p_id, int p_pos)); -extern void godot_js_tts_pause(); -extern void godot_js_tts_resume(); -extern void godot_js_tts_stop(); - -// Display -extern int godot_js_display_screen_dpi_get(); -extern double godot_js_display_pixel_ratio_get(); -extern void godot_js_display_alert(const char *p_text); -extern int godot_js_display_touchscreen_is_available(); -extern int godot_js_display_is_swap_ok_cancel(); -extern void godot_js_display_setup_canvas(int p_width, int p_height, int p_fullscreen, int p_hidpi); - -// Display canvas -extern void godot_js_display_canvas_focus(); -extern int godot_js_display_canvas_is_focused(); - -// Display window -extern void godot_js_display_desired_size_set(int p_width, int p_height); -extern int godot_js_display_size_update(); -extern void godot_js_display_window_size_get(int32_t *p_x, int32_t *p_y); -extern void godot_js_display_screen_size_get(int32_t *p_x, int32_t *p_y); -extern int godot_js_display_fullscreen_request(); -extern int godot_js_display_fullscreen_exit(); -extern void godot_js_display_window_title_set(const char *p_text); -extern void godot_js_display_window_icon_set(const uint8_t *p_ptr, int p_len); -extern int godot_js_display_has_webgl(int p_version); - -// Display clipboard -extern int godot_js_display_clipboard_set(const char *p_text); -extern int godot_js_display_clipboard_get(void (*p_callback)(const char *p_text)); - -// Display cursor -extern void godot_js_display_cursor_set_shape(const char *p_cursor); -extern int godot_js_display_cursor_is_hidden(); -extern void godot_js_display_cursor_set_custom_shape(const char *p_shape, const uint8_t *p_ptr, int p_len, int p_hotspot_x, int p_hotspot_y); -extern void godot_js_display_cursor_set_visible(int p_visible); -extern void godot_js_display_cursor_lock_set(int p_lock); -extern int godot_js_display_cursor_is_locked(); - -// Display listeners -extern void godot_js_display_fullscreen_cb(void (*p_callback)(int p_fullscreen)); -extern void godot_js_display_window_blur_cb(void (*p_callback)()); -extern void godot_js_display_notification_cb(void (*p_callback)(int p_notification), int p_enter, int p_exit, int p_in, int p_out); - -// Display Virtual Keyboard -extern int godot_js_display_vk_available(); -extern int godot_js_display_tts_available(); -extern void godot_js_display_vk_cb(void (*p_input)(const char *p_text, int p_cursor)); -extern void godot_js_display_vk_show(const char *p_text, int p_multiline, int p_start, int p_end); -extern void godot_js_display_vk_hide(); - -#ifdef __cplusplus -} -#endif - -#endif /* GODOT_JS_H */ diff --git a/platform/javascript/godot_webgl2.h b/platform/javascript/godot_webgl2.h deleted file mode 100644 index 7c357ff66d..0000000000 --- a/platform/javascript/godot_webgl2.h +++ /dev/null @@ -1,37 +0,0 @@ -/*************************************************************************/ -/* godot_webgl2.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef GODOT_WEBGL2_H -#define GODOT_WEBGL2_H - -#include "GLES3/gl3.h" -#include "webgl/webgl2.h" - -#endif diff --git a/platform/javascript/http_client_javascript.cpp b/platform/javascript/http_client_javascript.cpp deleted file mode 100644 index 32bdfed4c7..0000000000 --- a/platform/javascript/http_client_javascript.cpp +++ /dev/null @@ -1,272 +0,0 @@ -/*************************************************************************/ -/* http_client_javascript.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "http_client_javascript.h" - -void HTTPClientJavaScript::_parse_headers(int p_len, const char **p_headers, void *p_ref) { - HTTPClientJavaScript *client = static_cast<HTTPClientJavaScript *>(p_ref); - for (int i = 0; i < p_len; i++) { - client->response_headers.push_back(String::utf8(p_headers[i])); - } -} - -Error HTTPClientJavaScript::connect_to_host(const String &p_host, int p_port, bool p_ssl, bool p_verify_host) { - close(); - if (p_ssl && !p_verify_host) { - WARN_PRINT("Disabling HTTPClientJavaScript's host verification is not supported for the HTML5 platform, host will be verified"); - } - - port = p_port; - use_tls = p_ssl; - - host = p_host; - - String host_lower = host.to_lower(); - if (host_lower.begins_with("http://")) { - host = host.substr(7, host.length() - 7); - } else if (host_lower.begins_with("https://")) { - use_tls = true; - host = host.substr(8, host.length() - 8); - } - - ERR_FAIL_COND_V(host.length() < HOST_MIN_LEN, ERR_INVALID_PARAMETER); - - if (port < 0) { - if (use_tls) { - port = PORT_HTTPS; - } else { - port = PORT_HTTP; - } - } - - status = host.is_valid_ip_address() ? STATUS_CONNECTING : STATUS_RESOLVING; - - return OK; -} - -void HTTPClientJavaScript::set_connection(const Ref<StreamPeer> &p_connection) { - ERR_FAIL_MSG("Accessing an HTTPClientJavaScript's StreamPeer is not supported for the HTML5 platform."); -} - -Ref<StreamPeer> HTTPClientJavaScript::get_connection() const { - ERR_FAIL_V_MSG(Ref<RefCounted>(), "Accessing an HTTPClientJavaScript's StreamPeer is not supported for the HTML5 platform."); -} - -Error HTTPClientJavaScript::request(Method p_method, const String &p_url, const Vector<String> &p_headers, const uint8_t *p_body, int p_body_len) { - ERR_FAIL_INDEX_V(p_method, METHOD_MAX, ERR_INVALID_PARAMETER); - ERR_FAIL_COND_V_MSG(p_method == METHOD_TRACE || p_method == METHOD_CONNECT, ERR_UNAVAILABLE, "HTTP methods TRACE and CONNECT are not supported for the HTML5 platform."); - ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_INVALID_PARAMETER); - ERR_FAIL_COND_V(host.is_empty(), ERR_UNCONFIGURED); - ERR_FAIL_COND_V(port < 0, ERR_UNCONFIGURED); - ERR_FAIL_COND_V(!p_url.begins_with("/"), ERR_INVALID_PARAMETER); - - Error err = verify_headers(p_headers); - if (err) { - return err; - } - - String url = (use_tls ? "https://" : "http://") + host + ":" + itos(port) + p_url; - Vector<CharString> keeper; - Vector<const char *> c_strings; - for (int i = 0; i < p_headers.size(); i++) { - keeper.push_back(p_headers[i].utf8()); - c_strings.push_back(keeper[i].get_data()); - } - if (js_id) { - godot_js_fetch_free(js_id); - } - js_id = godot_js_fetch_create(_methods[p_method], url.utf8().get_data(), c_strings.ptrw(), c_strings.size(), p_body, p_body_len); - status = STATUS_REQUESTING; - return OK; -} - -void HTTPClientJavaScript::close() { - host = ""; - port = -1; - use_tls = false; - status = STATUS_DISCONNECTED; - polled_response_code = 0; - response_headers.resize(0); - response_buffer.resize(0); - if (js_id) { - godot_js_fetch_free(js_id); - js_id = 0; - } -} - -HTTPClientJavaScript::Status HTTPClientJavaScript::get_status() const { - return status; -} - -bool HTTPClientJavaScript::has_response() const { - return response_headers.size() > 0; -} - -bool HTTPClientJavaScript::is_response_chunked() const { - return godot_js_fetch_is_chunked(js_id); -} - -int HTTPClientJavaScript::get_response_code() const { - return polled_response_code; -} - -Error HTTPClientJavaScript::get_response_headers(List<String> *r_response) { - if (!response_headers.size()) { - return ERR_INVALID_PARAMETER; - } - for (int i = 0; i < response_headers.size(); i++) { - r_response->push_back(response_headers[i]); - } - response_headers.clear(); - return OK; -} - -int64_t HTTPClientJavaScript::get_response_body_length() const { - return godot_js_fetch_body_length_get(js_id); -} - -PackedByteArray HTTPClientJavaScript::read_response_body_chunk() { - ERR_FAIL_COND_V(status != STATUS_BODY, PackedByteArray()); - - if (response_buffer.size() != read_limit) { - response_buffer.resize(read_limit); - } - int read = godot_js_fetch_read_chunk(js_id, response_buffer.ptrw(), read_limit); - - // Check if the stream is over. - godot_js_fetch_state_t state = godot_js_fetch_state_get(js_id); - if (state == GODOT_JS_FETCH_STATE_DONE) { - status = STATUS_DISCONNECTED; - } else if (state != GODOT_JS_FETCH_STATE_BODY) { - status = STATUS_CONNECTION_ERROR; - } - - PackedByteArray chunk; - if (!read) { - return chunk; - } - chunk.resize(read); - memcpy(chunk.ptrw(), response_buffer.ptr(), read); - return chunk; -} - -void HTTPClientJavaScript::set_blocking_mode(bool p_enable) { - ERR_FAIL_COND_MSG(p_enable, "HTTPClientJavaScript blocking mode is not supported for the HTML5 platform."); -} - -bool HTTPClientJavaScript::is_blocking_mode_enabled() const { - return false; -} - -void HTTPClientJavaScript::set_read_chunk_size(int p_size) { - read_limit = p_size; -} - -int HTTPClientJavaScript::get_read_chunk_size() const { - return read_limit; -} - -Error HTTPClientJavaScript::poll() { - switch (status) { - case STATUS_DISCONNECTED: - return ERR_UNCONFIGURED; - - case STATUS_RESOLVING: - status = STATUS_CONNECTING; - return OK; - - case STATUS_CONNECTING: - status = STATUS_CONNECTED; - return OK; - - case STATUS_CONNECTED: - return OK; - - case STATUS_BODY: { - godot_js_fetch_state_t state = godot_js_fetch_state_get(js_id); - if (state == GODOT_JS_FETCH_STATE_DONE) { - status = STATUS_DISCONNECTED; - } else if (state != GODOT_JS_FETCH_STATE_BODY) { - status = STATUS_CONNECTION_ERROR; - return ERR_CONNECTION_ERROR; - } - return OK; - } - - case STATUS_CONNECTION_ERROR: - return ERR_CONNECTION_ERROR; - - case STATUS_REQUESTING: { -#ifdef DEBUG_ENABLED - // forcing synchronous requests is not possible on the web - if (last_polling_frame == Engine::get_singleton()->get_process_frames()) { - WARN_PRINT("HTTPClientJavaScript polled multiple times in one frame, " - "but request cannot progress more than once per " - "frame on the HTML5 platform."); - } - last_polling_frame = Engine::get_singleton()->get_process_frames(); -#endif - - polled_response_code = godot_js_fetch_http_status_get(js_id); - godot_js_fetch_state_t js_state = godot_js_fetch_state_get(js_id); - if (js_state == GODOT_JS_FETCH_STATE_REQUESTING) { - return OK; - } else if (js_state == GODOT_JS_FETCH_STATE_ERROR) { - // Fetch is in error state. - status = STATUS_CONNECTION_ERROR; - return ERR_CONNECTION_ERROR; - } - if (godot_js_fetch_read_headers(js_id, &_parse_headers, this)) { - // Failed to parse headers. - status = STATUS_CONNECTION_ERROR; - return ERR_CONNECTION_ERROR; - } - status = STATUS_BODY; - break; - } - - default: - ERR_FAIL_V(ERR_BUG); - } - return OK; -} - -HTTPClient *HTTPClientJavaScript::_create_func() { - return memnew(HTTPClientJavaScript); -} - -HTTPClient *(*HTTPClient::_create)() = HTTPClientJavaScript::_create_func; - -HTTPClientJavaScript::HTTPClientJavaScript() { -} - -HTTPClientJavaScript::~HTTPClientJavaScript() { - close(); -} diff --git a/platform/javascript/http_client_javascript.h b/platform/javascript/http_client_javascript.h deleted file mode 100644 index 096aa6a153..0000000000 --- a/platform/javascript/http_client_javascript.h +++ /dev/null @@ -1,108 +0,0 @@ -/*************************************************************************/ -/* http_client_javascript.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef HTTP_CLIENT_JAVASCRIPT_H -#define HTTP_CLIENT_JAVASCRIPT_H - -#include "core/io/http_client.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "stddef.h" - -typedef enum { - GODOT_JS_FETCH_STATE_REQUESTING = 0, - GODOT_JS_FETCH_STATE_BODY = 1, - GODOT_JS_FETCH_STATE_DONE = 2, - GODOT_JS_FETCH_STATE_ERROR = -1, -} godot_js_fetch_state_t; - -extern int godot_js_fetch_create(const char *p_method, const char *p_url, const char **p_headers, int p_headers_len, const uint8_t *p_body, int p_body_len); -extern int godot_js_fetch_read_headers(int p_id, void (*parse_callback)(int p_size, const char **p_headers, void *p_ref), void *p_ref); -extern int godot_js_fetch_read_chunk(int p_id, uint8_t *p_buf, int p_buf_size); -extern void godot_js_fetch_free(int p_id); -extern godot_js_fetch_state_t godot_js_fetch_state_get(int p_id); -extern int godot_js_fetch_body_length_get(int p_id); -extern int godot_js_fetch_http_status_get(int p_id); -extern int godot_js_fetch_is_chunked(int p_id); - -#ifdef __cplusplus -} -#endif - -class HTTPClientJavaScript : public HTTPClient { -private: - int js_id = 0; - Status status = STATUS_DISCONNECTED; - - // 64 KiB by default (favors fast download speeds at the cost of memory usage). - int read_limit = 65536; - - String host; - int port = -1; - bool use_tls = false; - - int polled_response_code = 0; - Vector<String> response_headers; - Vector<uint8_t> response_buffer; - -#ifdef DEBUG_ENABLED - uint64_t last_polling_frame = 0; -#endif - - static void _parse_headers(int p_len, const char **p_headers, void *p_ref); - -public: - static HTTPClient *_create_func(); - - Error request(Method p_method, const String &p_url, const Vector<String> &p_headers, const uint8_t *p_body, int p_body_size) override; - - Error connect_to_host(const String &p_host, int p_port = -1, bool p_ssl = false, bool p_verify_host = true) override; - void set_connection(const Ref<StreamPeer> &p_connection) override; - Ref<StreamPeer> get_connection() const override; - void close() override; - Status get_status() const override; - bool has_response() const override; - bool is_response_chunked() const override; - int get_response_code() const override; - Error get_response_headers(List<String> *r_response) override; - int64_t get_response_body_length() const override; - PackedByteArray read_response_body_chunk() override; - void set_blocking_mode(bool p_enable) override; - bool is_blocking_mode_enabled() const override; - void set_read_chunk_size(int p_size) override; - int get_read_chunk_size() const override; - Error poll() override; - HTTPClientJavaScript(); - ~HTTPClientJavaScript(); -}; -#endif // HTTP_CLIENT_JAVASCRIPT_H diff --git a/platform/javascript/javascript_main.cpp b/platform/javascript/javascript_main.cpp deleted file mode 100644 index 307a80feea..0000000000 --- a/platform/javascript/javascript_main.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/*************************************************************************/ -/* javascript_main.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "core/config/engine.h" -#include "core/io/resource_loader.h" -#include "main/main.h" -#include "platform/javascript/display_server_javascript.h" -#include "platform/javascript/os_javascript.h" - -#include <emscripten/emscripten.h> -#include <stdlib.h> - -#include "godot_js.h" - -static OS_JavaScript *os = nullptr; -static uint64_t target_ticks = 0; - -void exit_callback() { - emscripten_cancel_main_loop(); // After this, we can exit! - Main::cleanup(); - int exit_code = OS_JavaScript::get_singleton()->get_exit_code(); - memdelete(os); - os = nullptr; - emscripten_force_exit(exit_code); // No matter that we call cancel_main_loop, regular "exit" will not work, forcing. -} - -void cleanup_after_sync() { - emscripten_set_main_loop(exit_callback, -1, false); -} - -void main_loop_callback() { - uint64_t current_ticks = os->get_ticks_usec(); - - bool force_draw = DisplayServerJavaScript::get_singleton()->check_size_force_redraw(); - if (force_draw) { - Main::force_redraw(); - } else if (current_ticks < target_ticks) { - return; // Skip frame. - } - - int target_fps = Engine::get_singleton()->get_target_fps(); - if (target_fps > 0) { - if (current_ticks - target_ticks > 1000000) { - // When the window loses focus, we stop getting updates and accumulate delay. - // For this reason, if the difference is too big, we reset target ticks to the current ticks. - target_ticks = current_ticks; - } - target_ticks += (uint64_t)(1000000 / target_fps); - } - if (os->main_loop_iterate()) { - emscripten_cancel_main_loop(); // Cancel current loop and wait for cleanup_after_sync. - godot_js_os_finish_async(cleanup_after_sync); - } -} - -/// When calling main, it is assumed FS is setup and synced. -extern EMSCRIPTEN_KEEPALIVE int godot_js_main(int argc, char *argv[]) { - os = new OS_JavaScript(); - - // We must override main when testing is enabled - TEST_MAIN_OVERRIDE - - Main::setup(argv[0], argc - 1, &argv[1]); - - // Ease up compatibility. - ResourceLoader::set_abort_on_missing_resources(false); - - Main::start(); - os->get_main_loop()->initialize(); -#ifdef TOOLS_ENABLED - if (Engine::get_singleton()->is_project_manager_hint() && FileAccess::exists("/tmp/preload.zip")) { - PackedStringArray ps; - ps.push_back("/tmp/preload.zip"); - os->get_main_loop()->emit_signal(SNAME("files_dropped"), ps, -1); - } -#endif - emscripten_set_main_loop(main_loop_callback, -1, false); - // Immediately run the first iteration. - // We are inside an animation frame, we want to immediately draw on the newly setup canvas. - main_loop_callback(); - - return 0; -} diff --git a/platform/javascript/javascript_runtime.cpp b/platform/javascript/javascript_runtime.cpp deleted file mode 100644 index 932d0d5cb6..0000000000 --- a/platform/javascript/javascript_runtime.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/*************************************************************************/ -/* javascript_runtime.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -extern int godot_js_main(int argc, char *argv[]); - -int main(int argc, char *argv[]) { - return godot_js_main(argc, argv); -} diff --git a/platform/javascript/javascript_singleton.cpp b/platform/javascript/javascript_singleton.cpp deleted file mode 100644 index 8dc7aba5f8..0000000000 --- a/platform/javascript/javascript_singleton.cpp +++ /dev/null @@ -1,366 +0,0 @@ -/*************************************************************************/ -/* javascript_singleton.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "api/javascript_singleton.h" - -#include "emscripten.h" -#include "os_javascript.h" - -extern "C" { -extern void godot_js_os_download_buffer(const uint8_t *p_buf, int p_buf_size, const char *p_name, const char *p_mime); -} - -#ifdef JAVASCRIPT_EVAL_ENABLED - -extern "C" { -typedef union { - int64_t i; - double r; - void *p; -} godot_js_wrapper_ex; - -typedef int (*GodotJSWrapperVariant2JSCallback)(const void **p_args, int p_pos, godot_js_wrapper_ex *r_val, void **p_lock); -typedef void (*GodotJSWrapperFreeLockCallback)(void **p_lock, int p_type); -extern int godot_js_wrapper_interface_get(const char *p_name); -extern int godot_js_wrapper_object_call(int p_id, const char *p_method, void **p_args, int p_argc, GodotJSWrapperVariant2JSCallback p_variant2js_callback, godot_js_wrapper_ex *p_cb_rval, void **p_lock, GodotJSWrapperFreeLockCallback p_lock_callback); -extern int godot_js_wrapper_object_get(int p_id, godot_js_wrapper_ex *p_val, const char *p_prop); -extern int godot_js_wrapper_object_getvar(int p_id, int p_type, godot_js_wrapper_ex *p_val); -extern int godot_js_wrapper_object_setvar(int p_id, int p_key_type, godot_js_wrapper_ex *p_key_ex, int p_val_type, godot_js_wrapper_ex *p_val_ex); -extern void godot_js_wrapper_object_set(int p_id, const char *p_name, int p_type, godot_js_wrapper_ex *p_val); -extern void godot_js_wrapper_object_unref(int p_id); -extern int godot_js_wrapper_create_cb(void *p_ref, void (*p_callback)(void *p_ref, int p_arg_id, int p_argc)); -extern void godot_js_wrapper_object_set_cb_ret(int p_type, godot_js_wrapper_ex *p_val); -extern int godot_js_wrapper_create_object(const char *p_method, void **p_args, int p_argc, GodotJSWrapperVariant2JSCallback p_variant2js_callback, godot_js_wrapper_ex *p_cb_rval, void **p_lock, GodotJSWrapperFreeLockCallback p_lock_callback); -}; - -class JavaScriptObjectImpl : public JavaScriptObject { -private: - friend class JavaScript; - - int _js_id = 0; - Callable _callable; - - static int _variant2js(const void **p_args, int p_pos, godot_js_wrapper_ex *r_val, void **p_lock); - static void _free_lock(void **p_lock, int p_type); - static Variant _js2variant(int p_type, godot_js_wrapper_ex *p_val); - static void *_alloc_variants(int p_size); - static void _callback(void *p_ref, int p_arg_id, int p_argc); - -protected: - bool _set(const StringName &p_name, const Variant &p_value) override; - bool _get(const StringName &p_name, Variant &r_ret) const override; - void _get_property_list(List<PropertyInfo> *p_list) const override; - -public: - Variant getvar(const Variant &p_key, bool *r_valid = nullptr) const override; - void setvar(const Variant &p_key, const Variant &p_value, bool *r_valid = nullptr) override; - Variant callp(const StringName &p_method, const Variant **p_args, int p_argc, Callable::CallError &r_error) override; - JavaScriptObjectImpl() {} - JavaScriptObjectImpl(int p_id) { _js_id = p_id; } - ~JavaScriptObjectImpl() { - if (_js_id) { - godot_js_wrapper_object_unref(_js_id); - } - } -}; - -bool JavaScriptObjectImpl::_set(const StringName &p_name, const Variant &p_value) { - ERR_FAIL_COND_V_MSG(!_js_id, false, "Invalid JS instance"); - const String name = p_name; - godot_js_wrapper_ex exchange; - void *lock = nullptr; - const Variant *v = &p_value; - int type = _variant2js((const void **)&v, 0, &exchange, &lock); - godot_js_wrapper_object_set(_js_id, name.utf8().get_data(), type, &exchange); - if (lock) { - _free_lock(&lock, type); - } - return true; -} - -bool JavaScriptObjectImpl::_get(const StringName &p_name, Variant &r_ret) const { - ERR_FAIL_COND_V_MSG(!_js_id, false, "Invalid JS instance"); - const String name = p_name; - godot_js_wrapper_ex exchange; - int type = godot_js_wrapper_object_get(_js_id, &exchange, name.utf8().get_data()); - r_ret = _js2variant(type, &exchange); - return true; -} - -Variant JavaScriptObjectImpl::getvar(const Variant &p_key, bool *r_valid) const { - if (r_valid) { - *r_valid = false; - } - godot_js_wrapper_ex exchange; - void *lock = nullptr; - const Variant *v = &p_key; - int prop_type = _variant2js((const void **)&v, 0, &exchange, &lock); - int type = godot_js_wrapper_object_getvar(_js_id, prop_type, &exchange); - if (lock) { - _free_lock(&lock, prop_type); - } - if (type < 0) { - return Variant(); - } - if (r_valid) { - *r_valid = true; - } - return _js2variant(type, &exchange); -} - -void JavaScriptObjectImpl::setvar(const Variant &p_key, const Variant &p_value, bool *r_valid) { - if (r_valid) { - *r_valid = false; - } - godot_js_wrapper_ex kex, vex; - void *klock = nullptr; - void *vlock = nullptr; - const Variant *kv = &p_key; - const Variant *vv = &p_value; - int ktype = _variant2js((const void **)&kv, 0, &kex, &klock); - int vtype = _variant2js((const void **)&vv, 0, &vex, &vlock); - int ret = godot_js_wrapper_object_setvar(_js_id, ktype, &kex, vtype, &vex); - if (klock) { - _free_lock(&klock, ktype); - } - if (vlock) { - _free_lock(&vlock, vtype); - } - if (ret == 0 && r_valid) { - *r_valid = true; - } -} - -void JavaScriptObjectImpl::_get_property_list(List<PropertyInfo> *p_list) const { -} - -void JavaScriptObjectImpl::_free_lock(void **p_lock, int p_type) { - ERR_FAIL_COND_MSG(*p_lock == nullptr, "No lock to free!"); - const Variant::Type type = (Variant::Type)p_type; - switch (type) { - case Variant::STRING: { - CharString *cs = (CharString *)(*p_lock); - memdelete(cs); - *p_lock = nullptr; - } break; - default: - ERR_FAIL_MSG("Unknown lock type to free. Likely a bug."); - } -} - -Variant JavaScriptObjectImpl::_js2variant(int p_type, godot_js_wrapper_ex *p_val) { - Variant::Type type = (Variant::Type)p_type; - switch (type) { - case Variant::BOOL: - return Variant((bool)p_val->i); - case Variant::INT: - return p_val->i; - case Variant::FLOAT: - return p_val->r; - case Variant::STRING: { - String out = String::utf8((const char *)p_val->p); - free(p_val->p); - return out; - } - case Variant::OBJECT: { - return memnew(JavaScriptObjectImpl(p_val->i)); - } - default: - return Variant(); - } -} - -int JavaScriptObjectImpl::_variant2js(const void **p_args, int p_pos, godot_js_wrapper_ex *r_val, void **p_lock) { - const Variant **args = (const Variant **)p_args; - const Variant *v = args[p_pos]; - Variant::Type type = v->get_type(); - switch (type) { - case Variant::BOOL: - r_val->i = v->operator bool() ? 1 : 0; - break; - case Variant::INT: { - const int64_t tmp = v->operator int64_t(); - if (tmp >= 1LL << 31) { - r_val->r = (double)tmp; - return Variant::FLOAT; - } - r_val->i = v->operator int64_t(); - } break; - case Variant::FLOAT: - r_val->r = v->operator real_t(); - break; - case Variant::STRING: { - CharString *cs = memnew(CharString(v->operator String().utf8())); - r_val->p = (void *)cs->get_data(); - *p_lock = (void *)cs; - } break; - case Variant::OBJECT: { - JavaScriptObject *js_obj = Object::cast_to<JavaScriptObject>(v->operator Object *()); - r_val->i = js_obj != nullptr ? ((JavaScriptObjectImpl *)js_obj)->_js_id : 0; - } break; - default: - break; - } - return type; -} - -Variant JavaScriptObjectImpl::callp(const StringName &p_method, const Variant **p_args, int p_argc, Callable::CallError &r_error) { - godot_js_wrapper_ex exchange; - const String method = p_method; - void *lock = nullptr; - const int type = godot_js_wrapper_object_call(_js_id, method.utf8().get_data(), (void **)p_args, p_argc, &_variant2js, &exchange, &lock, &_free_lock); - r_error.error = Callable::CallError::CALL_OK; - if (type < 0) { - r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL; - return Variant(); - } - return _js2variant(type, &exchange); -} - -void JavaScriptObjectImpl::_callback(void *p_ref, int p_args_id, int p_argc) { - const JavaScriptObjectImpl *obj = (JavaScriptObjectImpl *)p_ref; - ERR_FAIL_COND_MSG(obj->_callable.is_null(), "JavaScript callback failed."); - Vector<const Variant *> argp; - Array arg_arr; - for (int i = 0; i < p_argc; i++) { - godot_js_wrapper_ex exchange; - exchange.i = i; - int type = godot_js_wrapper_object_getvar(p_args_id, Variant::INT, &exchange); - arg_arr.push_back(_js2variant(type, &exchange)); - } - Variant arg = arg_arr; - const Variant *argv[1] = { &arg }; - Callable::CallError err; - Variant ret; - obj->_callable.call(argv, 1, ret, err); - - // Set return value - godot_js_wrapper_ex exchange; - void *lock = nullptr; - const Variant *v = &ret; - int type = _variant2js((const void **)&v, 0, &exchange, &lock); - godot_js_wrapper_object_set_cb_ret(type, &exchange); - if (lock) { - _free_lock(&lock, type); - } -} - -Ref<JavaScriptObject> JavaScript::create_callback(const Callable &p_callable) { - Ref<JavaScriptObjectImpl> out = memnew(JavaScriptObjectImpl); - out->_callable = p_callable; - out->_js_id = godot_js_wrapper_create_cb(out.ptr(), JavaScriptObjectImpl::_callback); - return out; -} - -Ref<JavaScriptObject> JavaScript::get_interface(const String &p_interface) { - int js_id = godot_js_wrapper_interface_get(p_interface.utf8().get_data()); - ERR_FAIL_COND_V_MSG(!js_id, Ref<JavaScriptObject>(), "No interface '" + p_interface + "' registered."); - return Ref<JavaScriptObject>(memnew(JavaScriptObjectImpl(js_id))); -} - -Variant JavaScript::_create_object_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { - if (p_argcount < 1) { - r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; - r_error.argument = 0; - return Ref<JavaScriptObject>(); - } - if (p_args[0]->get_type() != Variant::STRING) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::STRING; - return Ref<JavaScriptObject>(); - } - godot_js_wrapper_ex exchange; - const String object = *p_args[0]; - void *lock = nullptr; - const Variant **args = p_argcount > 1 ? &p_args[1] : nullptr; - const int type = godot_js_wrapper_create_object(object.utf8().get_data(), (void **)args, p_argcount - 1, &JavaScriptObjectImpl::_variant2js, &exchange, &lock, &JavaScriptObjectImpl::_free_lock); - r_error.error = Callable::CallError::CALL_OK; - if (type < 0) { - r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL; - return Ref<JavaScriptObject>(); - } - return JavaScriptObjectImpl::_js2variant(type, &exchange); -} - -extern "C" { -union js_eval_ret { - uint32_t b; - double d; - char *s; -}; - -extern int godot_js_eval(const char *p_js, int p_use_global_ctx, union js_eval_ret *p_union_ptr, void *p_byte_arr, void *p_byte_arr_write, void *(*p_callback)(void *p_ptr, void *p_ptr2, int p_len)); -} - -void *resize_PackedByteArray_and_open_write(void *p_arr, void *r_write, int p_len) { - PackedByteArray *arr = (PackedByteArray *)p_arr; - VectorWriteProxy<uint8_t> *write = (VectorWriteProxy<uint8_t> *)r_write; - arr->resize(p_len); - *write = arr->write; - return arr->ptrw(); -} - -Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) { - union js_eval_ret js_data; - PackedByteArray arr; - VectorWriteProxy<uint8_t> arr_write; - - Variant::Type return_type = static_cast<Variant::Type>(godot_js_eval(p_code.utf8().get_data(), p_use_global_exec_context, &js_data, &arr, &arr_write, resize_PackedByteArray_and_open_write)); - - switch (return_type) { - case Variant::BOOL: - return js_data.b; - case Variant::FLOAT: - return js_data.d; - case Variant::STRING: { - String str = String::utf8(js_data.s); - free(js_data.s); // Must free the string allocated in JS. - return str; - } - case Variant::PACKED_BYTE_ARRAY: - arr_write = VectorWriteProxy<uint8_t>(); - return arr; - default: - return Variant(); - } -} -#endif // JAVASCRIPT_EVAL_ENABLED - -void JavaScript::download_buffer(Vector<uint8_t> p_arr, const String &p_name, const String &p_mime) { - godot_js_os_download_buffer(p_arr.ptr(), p_arr.size(), p_name.utf8().get_data(), p_mime.utf8().get_data()); -} - -bool JavaScript::pwa_needs_update() const { - return OS_JavaScript::get_singleton()->pwa_needs_update(); -} -Error JavaScript::pwa_update() { - return OS_JavaScript::get_singleton()->pwa_update(); -} diff --git a/platform/javascript/js/engine/config.js b/platform/javascript/js/engine/config.js deleted file mode 100644 index 2e5e1ed0d1..0000000000 --- a/platform/javascript/js/engine/config.js +++ /dev/null @@ -1,357 +0,0 @@ -/** - * An object used to configure the Engine instance based on godot export options, and to override those in custom HTML - * templates if needed. - * - * @header Engine configuration - * @summary The Engine configuration object. This is just a typedef, create it like a regular object, e.g.: - * - * ``const MyConfig = { executable: 'godot', unloadAfterInit: false }`` - * - * @typedef {Object} EngineConfig - */ -const EngineConfig = {}; // eslint-disable-line no-unused-vars - -/** - * @struct - * @constructor - * @ignore - */ -const InternalConfig = function (initConfig) { // eslint-disable-line no-unused-vars - const cfg = /** @lends {InternalConfig.prototype} */ { - /** - * Whether the unload the engine automatically after the instance is initialized. - * - * @memberof EngineConfig - * @default - * @type {boolean} - */ - unloadAfterInit: true, - /** - * The HTML DOM Canvas object to use. - * - * By default, the first canvas element in the document will be used is none is specified. - * - * @memberof EngineConfig - * @default - * @type {?HTMLCanvasElement} - */ - canvas: null, - /** - * The name of the WASM file without the extension. (Set by Godot Editor export process). - * - * @memberof EngineConfig - * @default - * @type {string} - */ - executable: '', - /** - * An alternative name for the game pck to load. The executable name is used otherwise. - * - * @memberof EngineConfig - * @default - * @type {?string} - */ - mainPack: null, - /** - * Specify a language code to select the proper localization for the game. - * - * The browser locale will be used if none is specified. See complete list of - * :ref:`supported locales <doc_locales>`. - * - * @memberof EngineConfig - * @type {?string} - * @default - */ - locale: null, - /** - * The canvas resize policy determines how the canvas should be resized by Godot. - * - * ``0`` means Godot won't do any resizing. This is useful if you want to control the canvas size from - * javascript code in your template. - * - * ``1`` means Godot will resize the canvas on start, and when changing window size via engine functions. - * - * ``2`` means Godot will adapt the canvas size to match the whole browser window. - * - * @memberof EngineConfig - * @type {number} - * @default - */ - canvasResizePolicy: 2, - /** - * The arguments to be passed as command line arguments on startup. - * - * See :ref:`command line tutorial <doc_command_line_tutorial>`. - * - * **Note**: :js:meth:`startGame <Engine.prototype.startGame>` will always add the ``--main-pack`` argument. - * - * @memberof EngineConfig - * @type {Array<string>} - * @default - */ - args: [], - /** - * When enabled, the game canvas will automatically grab the focus when the engine starts. - * - * @memberof EngineConfig - * @type {boolean} - * @default - */ - focusCanvas: true, - /** - * When enabled, this will turn on experimental virtual keyboard support on mobile. - * - * @memberof EngineConfig - * @type {boolean} - * @default - */ - experimentalVK: false, - /** - * The progressive web app service worker to install. - * @memberof EngineConfig - * @default - * @type {string} - */ - serviceWorker: '', - /** - * @ignore - * @type {Array.<string>} - */ - persistentPaths: ['/userfs'], - /** - * @ignore - * @type {boolean} - */ - persistentDrops: false, - /** - * @ignore - * @type {Array.<string>} - */ - gdnativeLibs: [], - /** - * @ignore - * @type {Array.<string>} - */ - fileSizes: [], - /** - * A callback function for handling Godot's ``OS.execute`` calls. - * - * This is for example used in the Web Editor template to switch between project manager and editor, and for running the game. - * - * @callback EngineConfig.onExecute - * @param {string} path The path that Godot's wants executed. - * @param {Array.<string>} args The arguments of the "command" to execute. - */ - /** - * @ignore - * @type {?function(string, Array.<string>)} - */ - onExecute: null, - /** - * A callback function for being notified when the Godot instance quits. - * - * **Note**: This function will not be called if the engine crashes or become unresponsive. - * - * @callback EngineConfig.onExit - * @param {number} status_code The status code returned by Godot on exit. - */ - /** - * @ignore - * @type {?function(number)} - */ - onExit: null, - /** - * A callback function for displaying download progress. - * - * The function is called once per frame while downloading files, so the usage of ``requestAnimationFrame()`` - * is not necessary. - * - * If the callback function receives a total amount of bytes as 0, this means that it is impossible to calculate. - * Possible reasons include: - * - * - Files are delivered with server-side chunked compression - * - Files are delivered with server-side compression on Chromium - * - Not all file downloads have started yet (usually on servers without multi-threading) - * - * @callback EngineConfig.onProgress - * @param {number} current The current amount of downloaded bytes so far. - * @param {number} total The total amount of bytes to be downloaded. - */ - /** - * @ignore - * @type {?function(number, number)} - */ - onProgress: null, - /** - * A callback function for handling the standard output stream. This method should usually only be used in debug pages. - * - * By default, ``console.log()`` is used. - * - * @callback EngineConfig.onPrint - * @param {...*} [var_args] A variadic number of arguments to be printed. - */ - /** - * @ignore - * @type {?function(...*)} - */ - onPrint: function () { - console.log.apply(console, Array.from(arguments)); // eslint-disable-line no-console - }, - /** - * A callback function for handling the standard error stream. This method should usually only be used in debug pages. - * - * By default, ``console.error()`` is used. - * - * @callback EngineConfig.onPrintError - * @param {...*} [var_args] A variadic number of arguments to be printed as errors. - */ - /** - * @ignore - * @type {?function(...*)} - */ - onPrintError: function (var_args) { - console.error.apply(console, Array.from(arguments)); // eslint-disable-line no-console - }, - }; - - /** - * @ignore - * @struct - * @constructor - * @param {EngineConfig} opts - */ - function Config(opts) { - this.update(opts); - } - - Config.prototype = cfg; - - /** - * @ignore - * @param {EngineConfig} opts - */ - Config.prototype.update = function (opts) { - const config = opts || {}; - // NOTE: We must explicitly pass the default, accessing it via - // the key will fail due to closure compiler renames. - function parse(key, def) { - if (typeof (config[key]) === 'undefined') { - return def; - } - return config[key]; - } - // Module config - this.unloadAfterInit = parse('unloadAfterInit', this.unloadAfterInit); - this.onPrintError = parse('onPrintError', this.onPrintError); - this.onPrint = parse('onPrint', this.onPrint); - this.onProgress = parse('onProgress', this.onProgress); - - // Godot config - this.canvas = parse('canvas', this.canvas); - this.executable = parse('executable', this.executable); - this.mainPack = parse('mainPack', this.mainPack); - this.locale = parse('locale', this.locale); - this.canvasResizePolicy = parse('canvasResizePolicy', this.canvasResizePolicy); - this.persistentPaths = parse('persistentPaths', this.persistentPaths); - this.persistentDrops = parse('persistentDrops', this.persistentDrops); - this.experimentalVK = parse('experimentalVK', this.experimentalVK); - this.focusCanvas = parse('focusCanvas', this.focusCanvas); - this.serviceWorker = parse('serviceWorker', this.serviceWorker); - this.gdnativeLibs = parse('gdnativeLibs', this.gdnativeLibs); - this.fileSizes = parse('fileSizes', this.fileSizes); - this.args = parse('args', this.args); - this.onExecute = parse('onExecute', this.onExecute); - this.onExit = parse('onExit', this.onExit); - }; - - /** - * @ignore - * @param {string} loadPath - * @param {Response} response - */ - Config.prototype.getModuleConfig = function (loadPath, response) { - let r = response; - return { - 'print': this.onPrint, - 'printErr': this.onPrintError, - 'thisProgram': this.executable, - 'noExitRuntime': true, - 'dynamicLibraries': [`${loadPath}.side.wasm`], - 'instantiateWasm': function (imports, onSuccess) { - function done(result) { - onSuccess(result['instance'], result['module']); - } - if (typeof (WebAssembly.instantiateStreaming) !== 'undefined') { - WebAssembly.instantiateStreaming(Promise.resolve(r), imports).then(done); - } else { - r.arrayBuffer().then(function (buffer) { - WebAssembly.instantiate(buffer, imports).then(done); - }); - } - r = null; - return {}; - }, - 'locateFile': function (path) { - if (path.endsWith('.worker.js')) { - return `${loadPath}.worker.js`; - } else if (path.endsWith('.audio.worklet.js')) { - return `${loadPath}.audio.worklet.js`; - } else if (path.endsWith('.js')) { - return `${loadPath}.js`; - } else if (path.endsWith('.side.wasm')) { - return `${loadPath}.side.wasm`; - } else if (path.endsWith('.wasm')) { - return `${loadPath}.wasm`; - } - return path; - }, - }; - }; - - /** - * @ignore - * @param {function()} cleanup - */ - Config.prototype.getGodotConfig = function (cleanup) { - // Try to find a canvas - if (!(this.canvas instanceof HTMLCanvasElement)) { - const nodes = document.getElementsByTagName('canvas'); - if (nodes.length && nodes[0] instanceof HTMLCanvasElement) { - this.canvas = nodes[0]; - } - if (!this.canvas) { - throw new Error('No canvas found in page'); - } - } - // Canvas can grab focus on click, or key events won't work. - if (this.canvas.tabIndex < 0) { - this.canvas.tabIndex = 0; - } - - // Browser locale, or custom one if defined. - let locale = this.locale; - if (!locale) { - locale = navigator.languages ? navigator.languages[0] : navigator.language; - locale = locale.split('.')[0]; - } - const onExit = this.onExit; - - // Godot configuration. - return { - 'canvas': this.canvas, - 'canvasResizePolicy': this.canvasResizePolicy, - 'locale': locale, - 'persistentDrops': this.persistentDrops, - 'virtualKeyboard': this.experimentalVK, - 'focusCanvas': this.focusCanvas, - 'onExecute': this.onExecute, - 'onExit': function (p_code) { - cleanup(); // We always need to call the cleanup callback to free memory. - if (typeof (onExit) === 'function') { - onExit(p_code); - } - }, - }; - }; - return new Config(initConfig); -}; diff --git a/platform/javascript/js/engine/engine.externs.js b/platform/javascript/js/engine/engine.externs.js deleted file mode 100644 index 35a66a93ae..0000000000 --- a/platform/javascript/js/engine/engine.externs.js +++ /dev/null @@ -1,4 +0,0 @@ -var Godot; -var WebAssembly = {}; -WebAssembly.instantiate = function(buffer, imports) {}; -WebAssembly.instantiateStreaming = function(response, imports) {}; diff --git a/platform/javascript/js/engine/engine.js b/platform/javascript/js/engine/engine.js deleted file mode 100644 index d2ba595083..0000000000 --- a/platform/javascript/js/engine/engine.js +++ /dev/null @@ -1,281 +0,0 @@ -/** - * Projects exported for the Web expose the :js:class:`Engine` class to the JavaScript environment, that allows - * fine control over the engine's start-up process. - * - * This API is built in an asynchronous manner and requires basic understanding - * of `Promises <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises>`__. - * - * @module Engine - * @header HTML5 shell class reference - */ -const Engine = (function () { - const preloader = new Preloader(); - - let loadPromise = null; - let loadPath = ''; - let initPromise = null; - - /** - * @classdesc The ``Engine`` class provides methods for loading and starting exported projects on the Web. For default export - * settings, this is already part of the exported HTML page. To understand practical use of the ``Engine`` class, - * see :ref:`Custom HTML page for Web export <doc_customizing_html5_shell>`. - * - * @description Create a new Engine instance with the given configuration. - * - * @global - * @constructor - * @param {EngineConfig} initConfig The initial config for this instance. - */ - function Engine(initConfig) { // eslint-disable-line no-shadow - this.config = new InternalConfig(initConfig); - this.rtenv = null; - } - - /** - * Load the engine from the specified base path. - * - * @param {string} basePath Base path of the engine to load. - * @param {number=} [size=0] The file size if known. - * @returns {Promise} A Promise that resolves once the engine is loaded. - * - * @function Engine.load - */ - Engine.load = function (basePath, size) { - if (loadPromise == null) { - loadPath = basePath; - loadPromise = preloader.loadPromise(`${loadPath}.wasm`, size, true); - requestAnimationFrame(preloader.animateProgress); - } - return loadPromise; - }; - - /** - * Unload the engine to free memory. - * - * This method will be called automatically depending on the configuration. See :js:attr:`unloadAfterInit`. - * - * @function Engine.unload - */ - Engine.unload = function () { - loadPromise = null; - }; - - /** - * Check whether WebGL is available. Optionally, specify a particular version of WebGL to check for. - * - * @param {number=} [majorVersion=1] The major WebGL version to check for. - * @returns {boolean} If the given major version of WebGL is available. - * @function Engine.isWebGLAvailable - */ - Engine.isWebGLAvailable = function (majorVersion = 1) { - try { - return !!document.createElement('canvas').getContext(['webgl', 'webgl2'][majorVersion - 1]); - } catch (e) { /* Not available */ } - return false; - }; - - /** - * Safe Engine constructor, creates a new prototype for every new instance to avoid prototype pollution. - * @ignore - * @constructor - */ - function SafeEngine(initConfig) { - const proto = /** @lends Engine.prototype */ { - /** - * Initialize the engine instance. Optionally, pass the base path to the engine to load it, - * if it hasn't been loaded yet. See :js:meth:`Engine.load`. - * - * @param {string=} basePath Base path of the engine to load. - * @return {Promise} A ``Promise`` that resolves once the engine is loaded and initialized. - */ - init: function (basePath) { - if (initPromise) { - return initPromise; - } - if (loadPromise == null) { - if (!basePath) { - initPromise = Promise.reject(new Error('A base path must be provided when calling `init` and the engine is not loaded.')); - return initPromise; - } - Engine.load(basePath, this.config.fileSizes[`${basePath}.wasm`]); - } - const me = this; - function doInit(promise) { - // Care! Promise chaining is bogus with old emscripten versions. - // This caused a regression with the Mono build (which uses an older emscripten version). - // Make sure to test that when refactoring. - return new Promise(function (resolve, reject) { - promise.then(function (response) { - const cloned = new Response(response.clone().body, { 'headers': [['content-type', 'application/wasm']] }); - Godot(me.config.getModuleConfig(loadPath, cloned)).then(function (module) { - const paths = me.config.persistentPaths; - module['initFS'](paths).then(function (err) { - me.rtenv = module; - if (me.config.unloadAfterInit) { - Engine.unload(); - } - resolve(); - }); - }); - }); - }); - } - preloader.setProgressFunc(this.config.onProgress); - initPromise = doInit(loadPromise); - return initPromise; - }, - - /** - * Load a file so it is available in the instance's file system once it runs. Must be called **before** starting the - * instance. - * - * If not provided, the ``path`` is derived from the URL of the loaded file. - * - * @param {string|ArrayBuffer} file The file to preload. - * - * If a ``string`` the file will be loaded from that path. - * - * If an ``ArrayBuffer`` or a view on one, the buffer will used as the content of the file. - * - * @param {string=} path Path by which the file will be accessible. Required, if ``file`` is not a string. - * - * @returns {Promise} A Promise that resolves once the file is loaded. - */ - preloadFile: function (file, path) { - return preloader.preload(file, path, this.config.fileSizes[file]); - }, - - /** - * Start the engine instance using the given override configuration (if any). - * :js:meth:`startGame <Engine.prototype.startGame>` can be used in typical cases instead. - * - * This will initialize the instance if it is not initialized. For manual initialization, see :js:meth:`init <Engine.prototype.init>`. - * The engine must be loaded beforehand. - * - * Fails if a canvas cannot be found on the page, or not specified in the configuration. - * - * @param {EngineConfig} override An optional configuration override. - * @return {Promise} Promise that resolves once the engine started. - */ - start: function (override) { - this.config.update(override); - const me = this; - return me.init().then(function () { - if (!me.rtenv) { - return Promise.reject(new Error('The engine must be initialized before it can be started')); - } - - let config = {}; - try { - config = me.config.getGodotConfig(function () { - me.rtenv = null; - }); - } catch (e) { - return Promise.reject(e); - } - // Godot configuration. - me.rtenv['initConfig'](config); - - // Preload GDNative libraries. - const libs = []; - me.config.gdnativeLibs.forEach(function (lib) { - libs.push(me.rtenv['loadDynamicLibrary'](lib, { 'loadAsync': true })); - }); - return Promise.all(libs).then(function () { - return new Promise(function (resolve, reject) { - preloader.preloadedFiles.forEach(function (file) { - me.rtenv['copyToFS'](file.path, file.buffer); - }); - preloader.preloadedFiles.length = 0; // Clear memory - me.rtenv['callMain'](me.config.args); - initPromise = null; - if (me.config.serviceWorker && 'serviceWorker' in navigator) { - navigator.serviceWorker.register(me.config.serviceWorker); - } - resolve(); - }); - }); - }); - }, - - /** - * Start the game instance using the given configuration override (if any). - * - * This will initialize the instance if it is not initialized. For manual initialization, see :js:meth:`init <Engine.prototype.init>`. - * - * This will load the engine if it is not loaded, and preload the main pck. - * - * This method expects the initial config (or the override) to have both the :js:attr:`executable` and :js:attr:`mainPack` - * properties set (normally done by the editor during export). - * - * @param {EngineConfig} override An optional configuration override. - * @return {Promise} Promise that resolves once the game started. - */ - startGame: function (override) { - this.config.update(override); - // Add main-pack argument. - const exe = this.config.executable; - const pack = this.config.mainPack || `${exe}.pck`; - this.config.args = ['--main-pack', pack].concat(this.config.args); - // Start and init with execName as loadPath if not inited. - const me = this; - return Promise.all([ - this.init(exe), - this.preloadFile(pack, pack), - ]).then(function () { - return me.start.apply(me); - }); - }, - - /** - * Create a file at the specified ``path`` with the passed as ``buffer`` in the instance's file system. - * - * @param {string} path The location where the file will be created. - * @param {ArrayBuffer} buffer The content of the file. - */ - copyToFS: function (path, buffer) { - if (this.rtenv == null) { - throw new Error('Engine must be inited before copying files'); - } - this.rtenv['copyToFS'](path, buffer); - }, - - /** - * Request that the current instance quit. - * - * This is akin the user pressing the close button in the window manager, and will - * have no effect if the engine has crashed, or is stuck in a loop. - * - */ - requestQuit: function () { - if (this.rtenv) { - this.rtenv['request_quit'](); - } - }, - }; - - Engine.prototype = proto; - // Closure compiler exported instance methods. - Engine.prototype['init'] = Engine.prototype.init; - Engine.prototype['preloadFile'] = Engine.prototype.preloadFile; - Engine.prototype['start'] = Engine.prototype.start; - Engine.prototype['startGame'] = Engine.prototype.startGame; - Engine.prototype['copyToFS'] = Engine.prototype.copyToFS; - Engine.prototype['requestQuit'] = Engine.prototype.requestQuit; - // Also expose static methods as instance methods - Engine.prototype['load'] = Engine.load; - Engine.prototype['unload'] = Engine.unload; - Engine.prototype['isWebGLAvailable'] = Engine.isWebGLAvailable; - return new Engine(initConfig); - } - - // Closure compiler exported static methods. - SafeEngine['load'] = Engine.load; - SafeEngine['unload'] = Engine.unload; - SafeEngine['isWebGLAvailable'] = Engine.isWebGLAvailable; - - return SafeEngine; -}()); -if (typeof window !== 'undefined') { - window['Engine'] = Engine; -} diff --git a/platform/javascript/js/engine/preloader.js b/platform/javascript/js/engine/preloader.js deleted file mode 100644 index 564c68d264..0000000000 --- a/platform/javascript/js/engine/preloader.js +++ /dev/null @@ -1,133 +0,0 @@ -const Preloader = /** @constructor */ function () { // eslint-disable-line no-unused-vars - function getTrackedResponse(response, load_status) { - function onloadprogress(reader, controller) { - return reader.read().then(function (result) { - if (load_status.done) { - return Promise.resolve(); - } - if (result.value) { - controller.enqueue(result.value); - load_status.loaded += result.value.length; - } - if (!result.done) { - return onloadprogress(reader, controller); - } - load_status.done = true; - return Promise.resolve(); - }); - } - const reader = response.body.getReader(); - return new Response(new ReadableStream({ - start: function (controller) { - onloadprogress(reader, controller).then(function () { - controller.close(); - }); - }, - }), { headers: response.headers }); - } - - function loadFetch(file, tracker, fileSize, raw) { - tracker[file] = { - total: fileSize || 0, - loaded: 0, - done: false, - }; - return fetch(file).then(function (response) { - if (!response.ok) { - return Promise.reject(new Error(`Failed loading file '${file}'`)); - } - const tr = getTrackedResponse(response, tracker[file]); - if (raw) { - return Promise.resolve(tr); - } - return tr.arrayBuffer(); - }); - } - - function retry(func, attempts = 1) { - function onerror(err) { - if (attempts <= 1) { - return Promise.reject(err); - } - return new Promise(function (resolve, reject) { - setTimeout(function () { - retry(func, attempts - 1).then(resolve).catch(reject); - }, 1000); - }); - } - return func().catch(onerror); - } - - const DOWNLOAD_ATTEMPTS_MAX = 4; - const loadingFiles = {}; - const lastProgress = { loaded: 0, total: 0 }; - let progressFunc = null; - - const animateProgress = function () { - let loaded = 0; - let total = 0; - let totalIsValid = true; - let progressIsFinal = true; - - Object.keys(loadingFiles).forEach(function (file) { - const stat = loadingFiles[file]; - if (!stat.done) { - progressIsFinal = false; - } - if (!totalIsValid || stat.total === 0) { - totalIsValid = false; - total = 0; - } else { - total += stat.total; - } - loaded += stat.loaded; - }); - if (loaded !== lastProgress.loaded || total !== lastProgress.total) { - lastProgress.loaded = loaded; - lastProgress.total = total; - if (typeof progressFunc === 'function') { - progressFunc(loaded, total); - } - } - if (!progressIsFinal) { - requestAnimationFrame(animateProgress); - } - }; - - this.animateProgress = animateProgress; - - this.setProgressFunc = function (callback) { - progressFunc = callback; - }; - - this.loadPromise = function (file, fileSize, raw = false) { - return retry(loadFetch.bind(null, file, loadingFiles, fileSize, raw), DOWNLOAD_ATTEMPTS_MAX); - }; - - this.preloadedFiles = []; - this.preload = function (pathOrBuffer, destPath, fileSize) { - let buffer = null; - if (typeof pathOrBuffer === 'string') { - const me = this; - return this.loadPromise(pathOrBuffer, fileSize).then(function (buf) { - me.preloadedFiles.push({ - path: destPath || pathOrBuffer, - buffer: buf, - }); - return Promise.resolve(); - }); - } else if (pathOrBuffer instanceof ArrayBuffer) { - buffer = new Uint8Array(pathOrBuffer); - } else if (ArrayBuffer.isView(pathOrBuffer)) { - buffer = new Uint8Array(pathOrBuffer.buffer); - } - if (buffer) { - this.preloadedFiles.push({ - path: destPath, - buffer: pathOrBuffer, - }); - return Promise.resolve(); - } - return Promise.reject(new Error('Invalid object for preloading')); - }; -}; diff --git a/platform/javascript/js/jsdoc2rst/publish.js b/platform/javascript/js/jsdoc2rst/publish.js deleted file mode 100644 index ad9c0fbaaa..0000000000 --- a/platform/javascript/js/jsdoc2rst/publish.js +++ /dev/null @@ -1,354 +0,0 @@ -/* eslint-disable strict */ - -'use strict'; - -const fs = require('fs'); - -class JSDoclet { - constructor(doc) { - this.doc = doc; - this.description = doc['description'] || ''; - this.name = doc['name'] || 'unknown'; - this.longname = doc['longname'] || ''; - this.types = []; - if (doc['type'] && doc['type']['names']) { - this.types = doc['type']['names'].slice(); - } - this.type = this.types.length > 0 ? this.types.join('\\|') : '*'; - this.variable = doc['variable'] || false; - this.kind = doc['kind'] || ''; - this.memberof = doc['memberof'] || null; - this.scope = doc['scope'] || ''; - this.members = []; - this.optional = doc['optional'] || false; - this.defaultvalue = doc['defaultvalue']; - this.summary = doc['summary'] || null; - this.classdesc = doc['classdesc'] || null; - - // Parameters (functions) - this.params = []; - this.returns = doc['returns'] ? doc['returns'][0]['type']['names'][0] : 'void'; - this.returns_desc = doc['returns'] ? doc['returns'][0]['description'] : null; - - this.params = (doc['params'] || []).slice().map((p) => new JSDoclet(p)); - - // Custom tags - this.tags = doc['tags'] || []; - this.header = this.tags.filter((t) => t['title'] === 'header').map((t) => t['text']).pop() || null; - } - - add_member(obj) { - this.members.push(obj); - } - - is_static() { - return this.scope === 'static'; - } - - is_instance() { - return this.scope === 'instance'; - } - - is_object() { - return this.kind === 'Object' || (this.kind === 'typedef' && this.type === 'Object'); - } - - is_class() { - return this.kind === 'class'; - } - - is_function() { - return this.kind === 'function' || (this.kind === 'typedef' && this.type === 'function'); - } - - is_module() { - return this.kind === 'module'; - } -} - -function format_table(f, data, depth = 0) { - if (!data.length) { - return; - } - - const column_sizes = new Array(data[0].length).fill(0); - - data.forEach((row) => { - row.forEach((e, idx) => { - column_sizes[idx] = Math.max(e.length, column_sizes[idx]); - }); - }); - - const indent = ' '.repeat(depth); - let sep = indent; - column_sizes.forEach((size) => { - sep += '+'; - sep += '-'.repeat(size + 2); - }); - sep += '+\n'; - f.write(sep); - - data.forEach((row) => { - let row_text = `${indent}|`; - row.forEach((entry, idx) => { - row_text += ` ${entry.padEnd(column_sizes[idx])} |`; - }); - row_text += '\n'; - f.write(row_text); - f.write(sep); - }); - - f.write('\n'); -} - -function make_header(header, sep) { - return `${header}\n${sep.repeat(header.length)}\n\n`; -} - -function indent_multiline(text, depth) { - const indent = ' '.repeat(depth); - return text.split('\n').map((l) => (l === '' ? l : indent + l)).join('\n'); -} - -function make_rst_signature(obj, types = false, style = false) { - let out = ''; - const fmt = style ? '*' : ''; - obj.params.forEach((arg, idx) => { - if (idx > 0) { - if (arg.optional) { - out += ` ${fmt}[`; - } - out += ', '; - } else { - out += ' '; - if (arg.optional) { - out += `${fmt}[ `; - } - } - if (types) { - out += `${arg.type} `; - } - const variable = arg.variable ? '...' : ''; - const defval = arg.defaultvalue !== undefined ? `=${arg.defaultvalue}` : ''; - out += `${variable}${arg.name}${defval}`; - if (arg.optional) { - out += ` ]${fmt}`; - } - }); - out += ' '; - return out; -} - -function make_rst_param(f, obj, depth = 0) { - const indent = ' '.repeat(depth * 3); - f.write(indent); - f.write(`:param ${obj.type} ${obj.name}:\n`); - f.write(indent_multiline(obj.description, (depth + 1) * 3)); - f.write('\n\n'); -} - -function make_rst_attribute(f, obj, depth = 0, brief = false) { - const indent = ' '.repeat(depth * 3); - f.write(indent); - f.write(`.. js:attribute:: ${obj.name}\n\n`); - - if (brief) { - if (obj.summary) { - f.write(indent_multiline(obj.summary, (depth + 1) * 3)); - } - f.write('\n\n'); - return; - } - - f.write(indent_multiline(obj.description, (depth + 1) * 3)); - f.write('\n\n'); - - f.write(indent); - f.write(` :type: ${obj.type}\n\n`); - - if (obj.defaultvalue !== undefined) { - let defval = obj.defaultvalue; - if (defval === '') { - defval = '""'; - } - f.write(indent); - f.write(` :value: \`\`${defval}\`\`\n\n`); - } -} - -function make_rst_function(f, obj, depth = 0) { - let prefix = ''; - if (obj.is_instance()) { - prefix = 'prototype.'; - } - - const indent = ' '.repeat(depth * 3); - const sig = make_rst_signature(obj); - f.write(indent); - f.write(`.. js:function:: ${prefix}${obj.name}(${sig})\n`); - f.write('\n'); - - f.write(indent_multiline(obj.description, (depth + 1) * 3)); - f.write('\n\n'); - - obj.params.forEach((param) => { - make_rst_param(f, param, depth + 1); - }); - - if (obj.returns !== 'void') { - f.write(indent); - f.write(' :return:\n'); - f.write(indent_multiline(obj.returns_desc, (depth + 2) * 3)); - f.write('\n\n'); - f.write(indent); - f.write(` :rtype: ${obj.returns}\n\n`); - } -} - -function make_rst_object(f, obj) { - let brief = false; - // Our custom header flag. - if (obj.header !== null) { - f.write(make_header(obj.header, '-')); - f.write(`${obj.description}\n\n`); - brief = true; - } - - // Format members table and descriptions - const data = [['type', 'name']].concat(obj.members.map((m) => [m.type, `:js:attr:\`${m.name}\``])); - - f.write(make_header('Properties', '^')); - format_table(f, data, 0); - - make_rst_attribute(f, obj, 0, brief); - - if (!obj.members.length) { - return; - } - - f.write(' **Property Descriptions**\n\n'); - - // Properties first - obj.members.filter((m) => !m.is_function()).forEach((m) => { - make_rst_attribute(f, m, 1); - }); - - // Callbacks last - obj.members.filter((m) => m.is_function()).forEach((m) => { - make_rst_function(f, m, 1); - }); -} - -function make_rst_class(f, obj) { - const header = obj.header ? obj.header : obj.name; - f.write(make_header(header, '-')); - - if (obj.classdesc) { - f.write(`${obj.classdesc}\n\n`); - } - - const funcs = obj.members.filter((m) => m.is_function()); - function make_data(m) { - const base = m.is_static() ? obj.name : `${obj.name}.prototype`; - const params = make_rst_signature(m, true, true); - const sig = `:js:attr:\`${m.name} <${base}.${m.name}>\` **(**${params}**)**`; - return [m.returns, sig]; - } - const sfuncs = funcs.filter((m) => m.is_static()); - const ifuncs = funcs.filter((m) => !m.is_static()); - - f.write(make_header('Static Methods', '^')); - format_table(f, sfuncs.map((m) => make_data(m))); - - f.write(make_header('Instance Methods', '^')); - format_table(f, ifuncs.map((m) => make_data(m))); - - const sig = make_rst_signature(obj); - f.write(`.. js:class:: ${obj.name}(${sig})\n\n`); - f.write(indent_multiline(obj.description, 3)); - f.write('\n\n'); - - obj.params.forEach((p) => { - make_rst_param(f, p, 1); - }); - - f.write(' **Static Methods**\n\n'); - sfuncs.forEach((m) => { - make_rst_function(f, m, 1); - }); - - f.write(' **Instance Methods**\n\n'); - ifuncs.forEach((m) => { - make_rst_function(f, m, 1); - }); -} - -function make_rst_module(f, obj) { - const header = obj.header !== null ? obj.header : obj.name; - f.write(make_header(header, '=')); - f.write(obj.description); - f.write('\n\n'); -} - -function write_base_object(f, obj) { - if (obj.is_object()) { - make_rst_object(f, obj); - } else if (obj.is_function()) { - make_rst_function(f, obj); - } else if (obj.is_class()) { - make_rst_class(f, obj); - } else if (obj.is_module()) { - make_rst_module(f, obj); - } -} - -function generate(f, docs) { - const globs = []; - const SYMBOLS = {}; - docs.filter((d) => !d.ignore && d.kind !== 'package').forEach((d) => { - SYMBOLS[d.name] = d; - if (d.memberof) { - const up = SYMBOLS[d.memberof]; - if (up === undefined) { - console.log(d); // eslint-disable-line no-console - console.log(`Undefined symbol! ${d.memberof}`); // eslint-disable-line no-console - throw new Error('Undefined symbol!'); - } - SYMBOLS[d.memberof].add_member(d); - } else { - globs.push(d); - } - }); - - f.write('.. _doc_html5_shell_classref:\n\n'); - globs.forEach((obj) => write_base_object(f, obj)); -} - -/** - * Generate documentation output. - * - * @param {TAFFY} data - A TaffyDB collection representing - * all the symbols documented in your code. - * @param {object} opts - An object with options information. - */ -exports.publish = function (data, opts) { - const docs = data().get().filter((doc) => !doc.undocumented && !doc.ignore).map((doc) => new JSDoclet(doc)); - const dest = opts.destination; - if (dest === 'dry-run') { - process.stdout.write('Dry run... '); - generate({ - write: function () { /* noop */ }, - }, docs); - process.stdout.write('Okay!\n'); - return; - } - if (dest !== '' && !dest.endsWith('.rst')) { - throw new Error('Destination file must be either a ".rst" file, or an empty string (for printing to stdout)'); - } - if (dest !== '') { - const f = fs.createWriteStream(dest); - generate(f, docs); - } else { - generate(process.stdout, docs); - } -}; diff --git a/platform/javascript/js/libs/audio.worklet.js b/platform/javascript/js/libs/audio.worklet.js deleted file mode 100644 index ea4d8cb221..0000000000 --- a/platform/javascript/js/libs/audio.worklet.js +++ /dev/null @@ -1,211 +0,0 @@ -/*************************************************************************/ -/* audio.worklet.js */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -class RingBuffer { - constructor(p_buffer, p_state, p_threads) { - this.buffer = p_buffer; - this.avail = p_state; - this.threads = p_threads; - this.rpos = 0; - this.wpos = 0; - } - - data_left() { - return this.threads ? Atomics.load(this.avail, 0) : this.avail; - } - - space_left() { - return this.buffer.length - this.data_left(); - } - - read(output) { - const size = this.buffer.length; - let from = 0; - let to_write = output.length; - if (this.rpos + to_write > size) { - const high = size - this.rpos; - output.set(this.buffer.subarray(this.rpos, size)); - from = high; - to_write -= high; - this.rpos = 0; - } - if (to_write) { - output.set(this.buffer.subarray(this.rpos, this.rpos + to_write), from); - } - this.rpos += to_write; - if (this.threads) { - Atomics.add(this.avail, 0, -output.length); - Atomics.notify(this.avail, 0); - } else { - this.avail -= output.length; - } - } - - write(p_buffer) { - const to_write = p_buffer.length; - const mw = this.buffer.length - this.wpos; - if (mw >= to_write) { - this.buffer.set(p_buffer, this.wpos); - this.wpos += to_write; - if (mw === to_write) { - this.wpos = 0; - } - } else { - const high = p_buffer.subarray(0, mw); - const low = p_buffer.subarray(mw); - this.buffer.set(high, this.wpos); - this.buffer.set(low); - this.wpos = low.length; - } - if (this.threads) { - Atomics.add(this.avail, 0, to_write); - Atomics.notify(this.avail, 0); - } else { - this.avail += to_write; - } - } -} - -class GodotProcessor extends AudioWorkletProcessor { - constructor() { - super(); - this.threads = false; - this.running = true; - this.lock = null; - this.notifier = null; - this.output = null; - this.output_buffer = new Float32Array(); - this.input = null; - this.input_buffer = new Float32Array(); - this.port.onmessage = (event) => { - const cmd = event.data['cmd']; - const data = event.data['data']; - this.parse_message(cmd, data); - }; - } - - process_notify() { - if (this.notifier) { - Atomics.add(this.notifier, 0, 1); - Atomics.notify(this.notifier, 0); - } - } - - parse_message(p_cmd, p_data) { - if (p_cmd === 'start' && p_data) { - const state = p_data[0]; - let idx = 0; - this.threads = true; - this.lock = state.subarray(idx, ++idx); - this.notifier = state.subarray(idx, ++idx); - const avail_in = state.subarray(idx, ++idx); - const avail_out = state.subarray(idx, ++idx); - this.input = new RingBuffer(p_data[1], avail_in, true); - this.output = new RingBuffer(p_data[2], avail_out, true); - } else if (p_cmd === 'stop') { - this.running = false; - this.output = null; - this.input = null; - } else if (p_cmd === 'start_nothreads') { - this.output = new RingBuffer(p_data[0], p_data[0].length, false); - } else if (p_cmd === 'chunk') { - this.output.write(p_data); - } - } - - static array_has_data(arr) { - return arr.length && arr[0].length && arr[0][0].length; - } - - process(inputs, outputs, parameters) { - if (!this.running) { - return false; // Stop processing. - } - if (this.output === null) { - return true; // Not ready yet, keep processing. - } - const process_input = GodotProcessor.array_has_data(inputs); - if (process_input) { - const input = inputs[0]; - const chunk = input[0].length * input.length; - if (this.input_buffer.length !== chunk) { - this.input_buffer = new Float32Array(chunk); - } - if (!this.threads) { - GodotProcessor.write_input(this.input_buffer, input); - this.port.postMessage({ 'cmd': 'input', 'data': this.input_buffer }); - } else if (this.input.space_left() >= chunk) { - GodotProcessor.write_input(this.input_buffer, input); - this.input.write(this.input_buffer); - } else { - this.port.postMessage('Input buffer is full! Skipping input frame.'); - } - } - const process_output = GodotProcessor.array_has_data(outputs); - if (process_output) { - const output = outputs[0]; - const chunk = output[0].length * output.length; - if (this.output_buffer.length !== chunk) { - this.output_buffer = new Float32Array(chunk); - } - if (this.output.data_left() >= chunk) { - this.output.read(this.output_buffer); - GodotProcessor.write_output(output, this.output_buffer); - if (!this.threads) { - this.port.postMessage({ 'cmd': 'read', 'data': chunk }); - } - } else { - this.port.postMessage('Output buffer has not enough frames! Skipping output frame.'); - } - } - this.process_notify(); - return true; - } - - static write_output(dest, source) { - const channels = dest.length; - for (let ch = 0; ch < channels; ch++) { - for (let sample = 0; sample < dest[ch].length; sample++) { - dest[ch][sample] = source[sample * channels + ch]; - } - } - } - - static write_input(dest, source) { - const channels = source.length; - for (let ch = 0; ch < channels; ch++) { - for (let sample = 0; sample < source[ch].length; sample++) { - dest[sample * channels + ch] = source[ch][sample]; - } - } - } -} - -registerProcessor('godot-processor', GodotProcessor); diff --git a/platform/javascript/js/libs/library_godot_audio.js b/platform/javascript/js/libs/library_godot_audio.js deleted file mode 100644 index 756c1ac595..0000000000 --- a/platform/javascript/js/libs/library_godot_audio.js +++ /dev/null @@ -1,484 +0,0 @@ -/*************************************************************************/ -/* library_godot_audio.js */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -const GodotAudio = { - $GodotAudio__deps: ['$GodotRuntime', '$GodotOS'], - $GodotAudio: { - ctx: null, - input: null, - driver: null, - interval: 0, - - init: function (mix_rate, latency, onstatechange, onlatencyupdate) { - const opts = {}; - // If mix_rate is 0, let the browser choose. - if (mix_rate) { - opts['sampleRate'] = mix_rate; - } - // Do not specify, leave 'interactive' for good performance. - // opts['latencyHint'] = latency / 1000; - const ctx = new (window.AudioContext || window.webkitAudioContext)(opts); - GodotAudio.ctx = ctx; - ctx.onstatechange = function () { - let state = 0; - switch (ctx.state) { - case 'suspended': - state = 0; - break; - case 'running': - state = 1; - break; - case 'closed': - state = 2; - break; - - // no default - } - onstatechange(state); - }; - ctx.onstatechange(); // Immediately notify state. - // Update computed latency - GodotAudio.interval = setInterval(function () { - let computed_latency = 0; - if (ctx.baseLatency) { - computed_latency += GodotAudio.ctx.baseLatency; - } - if (ctx.outputLatency) { - computed_latency += GodotAudio.ctx.outputLatency; - } - onlatencyupdate(computed_latency); - }, 1000); - GodotOS.atexit(GodotAudio.close_async); - return ctx.destination.channelCount; - }, - - create_input: function (callback) { - if (GodotAudio.input) { - return 0; // Already started. - } - function gotMediaInput(stream) { - try { - GodotAudio.input = GodotAudio.ctx.createMediaStreamSource(stream); - callback(GodotAudio.input); - } catch (e) { - GodotRuntime.error('Failed creaating input.', e); - } - } - if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { - navigator.mediaDevices.getUserMedia({ - 'audio': true, - }).then(gotMediaInput, function (e) { - GodotRuntime.error('Error getting user media.', e); - }); - } else { - if (!navigator.getUserMedia) { - navigator.getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia; - } - if (!navigator.getUserMedia) { - GodotRuntime.error('getUserMedia not available.'); - return 1; - } - navigator.getUserMedia({ - 'audio': true, - }, gotMediaInput, function (e) { - GodotRuntime.print(e); - }); - } - return 0; - }, - - close_async: function (resolve, reject) { - const ctx = GodotAudio.ctx; - GodotAudio.ctx = null; - // Audio was not initialized. - if (!ctx) { - resolve(); - return; - } - // Remove latency callback - if (GodotAudio.interval) { - clearInterval(GodotAudio.interval); - GodotAudio.interval = 0; - } - // Disconnect input, if it was started. - if (GodotAudio.input) { - GodotAudio.input.disconnect(); - GodotAudio.input = null; - } - // Disconnect output - let closed = Promise.resolve(); - if (GodotAudio.driver) { - closed = GodotAudio.driver.close(); - } - closed.then(function () { - return ctx.close(); - }).then(function () { - ctx.onstatechange = null; - resolve(); - }).catch(function (e) { - ctx.onstatechange = null; - GodotRuntime.error('Error closing AudioContext', e); - resolve(); - }); - }, - }, - - godot_audio_is_available__sig: 'i', - godot_audio_is_available__proxy: 'sync', - godot_audio_is_available: function () { - if (!(window.AudioContext || window.webkitAudioContext)) { - return 0; - } - return 1; - }, - - godot_audio_has_worklet__sig: 'i', - godot_audio_has_worklet: function () { - return (GodotAudio.ctx && GodotAudio.ctx.audioWorklet) ? 1 : 0; - }, - - godot_audio_has_script_processor__sig: 'i', - godot_audio_has_script_processor: function () { - return (GodotAudio.ctx && GodotAudio.ctx.createScriptProcessor) ? 1 : 0; - }, - - godot_audio_init__sig: 'iiiii', - godot_audio_init: function (p_mix_rate, p_latency, p_state_change, p_latency_update) { - const statechange = GodotRuntime.get_func(p_state_change); - const latencyupdate = GodotRuntime.get_func(p_latency_update); - const mix_rate = GodotRuntime.getHeapValue(p_mix_rate, 'i32'); - const channels = GodotAudio.init(mix_rate, p_latency, statechange, latencyupdate); - GodotRuntime.setHeapValue(p_mix_rate, GodotAudio.ctx.sampleRate, 'i32'); - return channels; - }, - - godot_audio_resume__sig: 'v', - godot_audio_resume: function () { - if (GodotAudio.ctx && GodotAudio.ctx.state !== 'running') { - GodotAudio.ctx.resume(); - } - }, - - godot_audio_capture_start__proxy: 'sync', - godot_audio_capture_start__sig: 'i', - godot_audio_capture_start: function () { - return GodotAudio.create_input(function (input) { - input.connect(GodotAudio.driver.get_node()); - }); - }, - - godot_audio_capture_stop__proxy: 'sync', - godot_audio_capture_stop__sig: 'v', - godot_audio_capture_stop: function () { - if (GodotAudio.input) { - const tracks = GodotAudio.input['mediaStream']['getTracks'](); - for (let i = 0; i < tracks.length; i++) { - tracks[i]['stop'](); - } - GodotAudio.input.disconnect(); - GodotAudio.input = null; - } - }, -}; - -autoAddDeps(GodotAudio, '$GodotAudio'); -mergeInto(LibraryManager.library, GodotAudio); - -/** - * The AudioWorklet API driver, used when threads are available. - */ -const GodotAudioWorklet = { - $GodotAudioWorklet__deps: ['$GodotAudio', '$GodotConfig'], - $GodotAudioWorklet: { - promise: null, - worklet: null, - ring_buffer: null, - - create: function (channels) { - const path = GodotConfig.locate_file('godot.audio.worklet.js'); - GodotAudioWorklet.promise = GodotAudio.ctx.audioWorklet.addModule(path).then(function () { - GodotAudioWorklet.worklet = new AudioWorkletNode( - GodotAudio.ctx, - 'godot-processor', - { - 'outputChannelCount': [channels], - } - ); - return Promise.resolve(); - }); - GodotAudio.driver = GodotAudioWorklet; - }, - - start: function (in_buf, out_buf, state) { - GodotAudioWorklet.promise.then(function () { - const node = GodotAudioWorklet.worklet; - node.connect(GodotAudio.ctx.destination); - node.port.postMessage({ - 'cmd': 'start', - 'data': [state, in_buf, out_buf], - }); - node.port.onmessage = function (event) { - GodotRuntime.error(event.data); - }; - }); - }, - - start_no_threads: function (p_out_buf, p_out_size, out_callback, p_in_buf, p_in_size, in_callback) { - function RingBuffer() { - let wpos = 0; - let rpos = 0; - let pending_samples = 0; - const wbuf = new Float32Array(p_out_size); - - function send(port) { - if (pending_samples === 0) { - return; - } - const buffer = GodotRuntime.heapSub(HEAPF32, p_out_buf, p_out_size); - const size = buffer.length; - const tot_sent = pending_samples; - out_callback(wpos, pending_samples); - if (wpos + pending_samples >= size) { - const high = size - wpos; - wbuf.set(buffer.subarray(wpos, size)); - pending_samples -= high; - wpos = 0; - } - if (pending_samples > 0) { - wbuf.set(buffer.subarray(wpos, wpos + pending_samples), tot_sent - pending_samples); - } - port.postMessage({ 'cmd': 'chunk', 'data': wbuf.subarray(0, tot_sent) }); - wpos += pending_samples; - pending_samples = 0; - } - this.receive = function (recv_buf) { - const buffer = GodotRuntime.heapSub(HEAPF32, p_in_buf, p_in_size); - const from = rpos; - let to_write = recv_buf.length; - let high = 0; - if (rpos + to_write >= p_in_size) { - high = p_in_size - rpos; - buffer.set(recv_buf.subarray(0, high), rpos); - to_write -= high; - rpos = 0; - } - if (to_write) { - buffer.set(recv_buf.subarray(high, to_write), rpos); - } - in_callback(from, recv_buf.length); - rpos += to_write; - }; - this.consumed = function (size, port) { - pending_samples += size; - send(port); - }; - } - GodotAudioWorklet.ring_buffer = new RingBuffer(); - GodotAudioWorklet.promise.then(function () { - const node = GodotAudioWorklet.worklet; - const buffer = GodotRuntime.heapSlice(HEAPF32, p_out_buf, p_out_size); - node.connect(GodotAudio.ctx.destination); - node.port.postMessage({ - 'cmd': 'start_nothreads', - 'data': [buffer, p_in_size], - }); - node.port.onmessage = function (event) { - if (!GodotAudioWorklet.worklet) { - return; - } - if (event.data['cmd'] === 'read') { - const read = event.data['data']; - GodotAudioWorklet.ring_buffer.consumed(read, GodotAudioWorklet.worklet.port); - } else if (event.data['cmd'] === 'input') { - const buf = event.data['data']; - if (buf.length > p_in_size) { - GodotRuntime.error('Input chunk is too big'); - return; - } - GodotAudioWorklet.ring_buffer.receive(buf); - } else { - GodotRuntime.error(event.data); - } - }; - }); - }, - - get_node: function () { - return GodotAudioWorklet.worklet; - }, - - close: function () { - return new Promise(function (resolve, reject) { - if (GodotAudioWorklet.promise === null) { - return; - } - GodotAudioWorklet.promise.then(function () { - GodotAudioWorklet.worklet.port.postMessage({ - 'cmd': 'stop', - 'data': null, - }); - GodotAudioWorklet.worklet.disconnect(); - GodotAudioWorklet.worklet = null; - GodotAudioWorklet.promise = null; - resolve(); - }).catch(function (err) { /* aborted? */ }); - }); - }, - }, - - godot_audio_worklet_create__sig: 'ii', - godot_audio_worklet_create: function (channels) { - try { - GodotAudioWorklet.create(channels); - } catch (e) { - GodotRuntime.error('Error starting AudioDriverWorklet', e); - return 1; - } - return 0; - }, - - godot_audio_worklet_start__sig: 'viiiii', - godot_audio_worklet_start: function (p_in_buf, p_in_size, p_out_buf, p_out_size, p_state) { - const out_buffer = GodotRuntime.heapSub(HEAPF32, p_out_buf, p_out_size); - const in_buffer = GodotRuntime.heapSub(HEAPF32, p_in_buf, p_in_size); - const state = GodotRuntime.heapSub(HEAP32, p_state, 4); - GodotAudioWorklet.start(in_buffer, out_buffer, state); - }, - - godot_audio_worklet_start_no_threads__sig: 'viiiiii', - godot_audio_worklet_start_no_threads: function (p_out_buf, p_out_size, p_out_callback, p_in_buf, p_in_size, p_in_callback) { - const out_callback = GodotRuntime.get_func(p_out_callback); - const in_callback = GodotRuntime.get_func(p_in_callback); - GodotAudioWorklet.start_no_threads(p_out_buf, p_out_size, out_callback, p_in_buf, p_in_size, in_callback); - }, - - godot_audio_worklet_state_wait__sig: 'iiii', - godot_audio_worklet_state_wait: function (p_state, p_idx, p_expected, p_timeout) { - Atomics.wait(HEAP32, (p_state >> 2) + p_idx, p_expected, p_timeout); - return Atomics.load(HEAP32, (p_state >> 2) + p_idx); - }, - - godot_audio_worklet_state_add__sig: 'iiii', - godot_audio_worklet_state_add: function (p_state, p_idx, p_value) { - return Atomics.add(HEAP32, (p_state >> 2) + p_idx, p_value); - }, - - godot_audio_worklet_state_get__sig: 'iii', - godot_audio_worklet_state_get: function (p_state, p_idx) { - return Atomics.load(HEAP32, (p_state >> 2) + p_idx); - }, -}; - -autoAddDeps(GodotAudioWorklet, '$GodotAudioWorklet'); -mergeInto(LibraryManager.library, GodotAudioWorklet); - -/* - * The deprecated ScriptProcessorNode API, used when threads are disabled. - */ -const GodotAudioScript = { - $GodotAudioScript__deps: ['$GodotAudio'], - $GodotAudioScript: { - script: null, - - create: function (buffer_length, channel_count) { - GodotAudioScript.script = GodotAudio.ctx.createScriptProcessor(buffer_length, 2, channel_count); - GodotAudio.driver = GodotAudioScript; - return GodotAudioScript.script.bufferSize; - }, - - start: function (p_in_buf, p_in_size, p_out_buf, p_out_size, onprocess) { - GodotAudioScript.script.onaudioprocess = function (event) { - // Read input - const inb = GodotRuntime.heapSub(HEAPF32, p_in_buf, p_in_size); - const input = event.inputBuffer; - if (GodotAudio.input) { - const inlen = input.getChannelData(0).length; - for (let ch = 0; ch < 2; ch++) { - const data = input.getChannelData(ch); - for (let s = 0; s < inlen; s++) { - inb[s * 2 + ch] = data[s]; - } - } - } - - // Let Godot process the input/output. - onprocess(); - - // Write the output. - const outb = GodotRuntime.heapSub(HEAPF32, p_out_buf, p_out_size); - const output = event.outputBuffer; - const channels = output.numberOfChannels; - for (let ch = 0; ch < channels; ch++) { - const data = output.getChannelData(ch); - // Loop through samples and assign computed values. - for (let sample = 0; sample < data.length; sample++) { - data[sample] = outb[sample * channels + ch]; - } - } - }; - GodotAudioScript.script.connect(GodotAudio.ctx.destination); - }, - - get_node: function () { - return GodotAudioScript.script; - }, - - close: function () { - return new Promise(function (resolve, reject) { - GodotAudioScript.script.disconnect(); - GodotAudioScript.script.onaudioprocess = null; - GodotAudioScript.script = null; - resolve(); - }); - }, - }, - - godot_audio_script_create__sig: 'iii', - godot_audio_script_create: function (buffer_length, channel_count) { - const buf_len = GodotRuntime.getHeapValue(buffer_length, 'i32'); - try { - const out_len = GodotAudioScript.create(buf_len, channel_count); - GodotRuntime.setHeapValue(buffer_length, out_len, 'i32'); - } catch (e) { - GodotRuntime.error('Error starting AudioDriverScriptProcessor', e); - return 1; - } - return 0; - }, - - godot_audio_script_start__sig: 'viiiii', - godot_audio_script_start: function (p_in_buf, p_in_size, p_out_buf, p_out_size, p_cb) { - const onprocess = GodotRuntime.get_func(p_cb); - GodotAudioScript.start(p_in_buf, p_in_size, p_out_buf, p_out_size, onprocess); - }, -}; - -autoAddDeps(GodotAudioScript, '$GodotAudioScript'); -mergeInto(LibraryManager.library, GodotAudioScript); diff --git a/platform/javascript/js/libs/library_godot_display.js b/platform/javascript/js/libs/library_godot_display.js deleted file mode 100644 index 5997631bf8..0000000000 --- a/platform/javascript/js/libs/library_godot_display.js +++ /dev/null @@ -1,729 +0,0 @@ -/*************************************************************************/ -/* library_godot_display.js */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -const GodotDisplayVK = { - - $GodotDisplayVK__deps: ['$GodotRuntime', '$GodotConfig', '$GodotEventListeners'], - $GodotDisplayVK__postset: 'GodotOS.atexit(function(resolve, reject) { GodotDisplayVK.clear(); resolve(); });', - $GodotDisplayVK: { - textinput: null, - textarea: null, - - available: function () { - return GodotConfig.virtual_keyboard && 'ontouchstart' in window; - }, - - init: function (input_cb) { - function create(what) { - const elem = document.createElement(what); - elem.style.display = 'none'; - elem.style.position = 'absolute'; - elem.style.zIndex = '-1'; - elem.style.background = 'transparent'; - elem.style.padding = '0px'; - elem.style.margin = '0px'; - elem.style.overflow = 'hidden'; - elem.style.width = '0px'; - elem.style.height = '0px'; - elem.style.border = '0px'; - elem.style.outline = 'none'; - elem.readonly = true; - elem.disabled = true; - GodotEventListeners.add(elem, 'input', function (evt) { - const c_str = GodotRuntime.allocString(elem.value); - input_cb(c_str, elem.selectionEnd); - GodotRuntime.free(c_str); - }, false); - GodotEventListeners.add(elem, 'blur', function (evt) { - elem.style.display = 'none'; - elem.readonly = true; - elem.disabled = true; - }, false); - GodotConfig.canvas.insertAdjacentElement('beforebegin', elem); - return elem; - } - GodotDisplayVK.textinput = create('input'); - GodotDisplayVK.textarea = create('textarea'); - GodotDisplayVK.updateSize(); - }, - show: function (text, multiline, start, end) { - if (!GodotDisplayVK.textinput || !GodotDisplayVK.textarea) { - return; - } - if (GodotDisplayVK.textinput.style.display !== '' || GodotDisplayVK.textarea.style.display !== '') { - GodotDisplayVK.hide(); - } - GodotDisplayVK.updateSize(); - const elem = multiline ? GodotDisplayVK.textarea : GodotDisplayVK.textinput; - elem.readonly = false; - elem.disabled = false; - elem.value = text; - elem.style.display = 'block'; - elem.focus(); - elem.setSelectionRange(start, end); - }, - hide: function () { - if (!GodotDisplayVK.textinput || !GodotDisplayVK.textarea) { - return; - } - [GodotDisplayVK.textinput, GodotDisplayVK.textarea].forEach(function (elem) { - elem.blur(); - elem.style.display = 'none'; - elem.value = ''; - }); - }, - updateSize: function () { - if (!GodotDisplayVK.textinput || !GodotDisplayVK.textarea) { - return; - } - const rect = GodotConfig.canvas.getBoundingClientRect(); - function update(elem) { - elem.style.left = `${rect.left}px`; - elem.style.top = `${rect.top}px`; - elem.style.width = `${rect.width}px`; - elem.style.height = `${rect.height}px`; - } - update(GodotDisplayVK.textinput); - update(GodotDisplayVK.textarea); - }, - clear: function () { - if (GodotDisplayVK.textinput) { - GodotDisplayVK.textinput.remove(); - GodotDisplayVK.textinput = null; - } - if (GodotDisplayVK.textarea) { - GodotDisplayVK.textarea.remove(); - GodotDisplayVK.textarea = null; - } - }, - }, -}; -mergeInto(LibraryManager.library, GodotDisplayVK); - -/* - * Display server cursor helper. - * Keeps track of cursor status and custom shapes. - */ -const GodotDisplayCursor = { - $GodotDisplayCursor__deps: ['$GodotOS', '$GodotConfig'], - $GodotDisplayCursor__postset: 'GodotOS.atexit(function(resolve, reject) { GodotDisplayCursor.clear(); resolve(); });', - $GodotDisplayCursor: { - shape: 'auto', - visible: true, - cursors: {}, - set_style: function (style) { - GodotConfig.canvas.style.cursor = style; - }, - set_shape: function (shape) { - GodotDisplayCursor.shape = shape; - let css = shape; - if (shape in GodotDisplayCursor.cursors) { - const c = GodotDisplayCursor.cursors[shape]; - css = `url("${c.url}") ${c.x} ${c.y}, auto`; - } - if (GodotDisplayCursor.visible) { - GodotDisplayCursor.set_style(css); - } - }, - clear: function () { - GodotDisplayCursor.set_style(''); - GodotDisplayCursor.shape = 'auto'; - GodotDisplayCursor.visible = true; - Object.keys(GodotDisplayCursor.cursors).forEach(function (key) { - URL.revokeObjectURL(GodotDisplayCursor.cursors[key]); - delete GodotDisplayCursor.cursors[key]; - }); - }, - lockPointer: function () { - const canvas = GodotConfig.canvas; - if (canvas.requestPointerLock) { - canvas.requestPointerLock(); - } - }, - releasePointer: function () { - if (document.exitPointerLock) { - document.exitPointerLock(); - } - }, - isPointerLocked: function () { - return document.pointerLockElement === GodotConfig.canvas; - }, - }, -}; -mergeInto(LibraryManager.library, GodotDisplayCursor); - -const GodotDisplayScreen = { - $GodotDisplayScreen__deps: ['$GodotConfig', '$GodotOS', '$GL', 'emscripten_webgl_get_current_context'], - $GodotDisplayScreen: { - desired_size: [0, 0], - hidpi: true, - getPixelRatio: function () { - return GodotDisplayScreen.hidpi ? window.devicePixelRatio || 1 : 1; - }, - isFullscreen: function () { - const elem = document.fullscreenElement || document.mozFullscreenElement - || document.webkitFullscreenElement || document.msFullscreenElement; - if (elem) { - return elem === GodotConfig.canvas; - } - // But maybe knowing the element is not supported. - return document.fullscreen || document.mozFullScreen - || document.webkitIsFullscreen; - }, - hasFullscreen: function () { - return document.fullscreenEnabled || document.mozFullScreenEnabled - || document.webkitFullscreenEnabled; - }, - requestFullscreen: function () { - if (!GodotDisplayScreen.hasFullscreen()) { - return 1; - } - const canvas = GodotConfig.canvas; - try { - const promise = (canvas.requestFullscreen || canvas.msRequestFullscreen - || canvas.mozRequestFullScreen || canvas.mozRequestFullscreen - || canvas.webkitRequestFullscreen - ).call(canvas); - // Some browsers (Safari) return undefined. - // For the standard ones, we need to catch it. - if (promise) { - promise.catch(function () { - // nothing to do. - }); - } - } catch (e) { - return 1; - } - return 0; - }, - exitFullscreen: function () { - if (!GodotDisplayScreen.isFullscreen()) { - return 0; - } - try { - const promise = document.exitFullscreen(); - if (promise) { - promise.catch(function () { - // nothing to do. - }); - } - } catch (e) { - return 1; - } - return 0; - }, - _updateGL: function () { - const gl_context_handle = _emscripten_webgl_get_current_context(); // eslint-disable-line no-undef - const gl = GL.getContext(gl_context_handle); - if (gl) { - GL.resizeOffscreenFramebuffer(gl); - } - }, - updateSize: function () { - const isFullscreen = GodotDisplayScreen.isFullscreen(); - const wantsFullWindow = GodotConfig.canvas_resize_policy === 2; - const noResize = GodotConfig.canvas_resize_policy === 0; - const wwidth = GodotDisplayScreen.desired_size[0]; - const wheight = GodotDisplayScreen.desired_size[1]; - const canvas = GodotConfig.canvas; - let width = wwidth; - let height = wheight; - if (noResize) { - // Don't resize canvas, just update GL if needed. - if (canvas.width !== width || canvas.height !== height) { - GodotDisplayScreen.desired_size = [canvas.width, canvas.height]; - GodotDisplayScreen._updateGL(); - return 1; - } - return 0; - } - const scale = GodotDisplayScreen.getPixelRatio(); - if (isFullscreen || wantsFullWindow) { - // We need to match screen size. - width = window.innerWidth * scale; - height = window.innerHeight * scale; - } - const csw = `${width / scale}px`; - const csh = `${height / scale}px`; - if (canvas.style.width !== csw || canvas.style.height !== csh || canvas.width !== width || canvas.height !== height) { - // Size doesn't match. - // Resize canvas, set correct CSS pixel size, update GL. - canvas.width = width; - canvas.height = height; - canvas.style.width = csw; - canvas.style.height = csh; - GodotDisplayScreen._updateGL(); - return 1; - } - return 0; - }, - }, -}; -mergeInto(LibraryManager.library, GodotDisplayScreen); - -/** - * Display server interface. - * - * Exposes all the functions needed by DisplayServer implementation. - */ -const GodotDisplay = { - $GodotDisplay__deps: ['$GodotConfig', '$GodotRuntime', '$GodotDisplayCursor', '$GodotEventListeners', '$GodotDisplayScreen', '$GodotDisplayVK'], - $GodotDisplay: { - window_icon: '', - findDPI: function () { - function testDPI(dpi) { - return window.matchMedia(`(max-resolution: ${dpi}dpi)`).matches; - } - function bisect(low, high, func) { - const mid = parseInt(((high - low) / 2) + low, 10); - if (high - low <= 1) { - return func(high) ? high : low; - } - if (func(mid)) { - return bisect(low, mid, func); - } - return bisect(mid, high, func); - } - try { - const dpi = bisect(0, 800, testDPI); - return dpi >= 96 ? dpi : 96; - } catch (e) { - return 96; - } - }, - }, - - godot_js_display_is_swap_ok_cancel__sig: 'i', - godot_js_display_is_swap_ok_cancel: function () { - const win = (['Windows', 'Win64', 'Win32', 'WinCE']); - const plat = navigator.platform || ''; - if (win.indexOf(plat) !== -1) { - return 1; - } - return 0; - }, - - godot_js_tts_is_speaking__sig: 'i', - godot_js_tts_is_speaking: function () { - return window.speechSynthesis.speaking; - }, - - godot_js_tts_is_paused__sig: 'i', - godot_js_tts_is_paused: function () { - return window.speechSynthesis.paused; - }, - - godot_js_tts_get_voices__sig: 'vi', - godot_js_tts_get_voices: function (p_callback) { - const func = GodotRuntime.get_func(p_callback); - try { - const arr = []; - const voices = window.speechSynthesis.getVoices(); - for (let i = 0; i < voices.length; i++) { - arr.push(`${voices[i].lang};${voices[i].name}`); - } - const c_ptr = GodotRuntime.allocStringArray(arr); - func(arr.length, c_ptr); - GodotRuntime.freeStringArray(c_ptr, arr.length); - } catch (e) { - // Fail graciously. - } - }, - - godot_js_tts_speak__sig: 'viiiffii', - godot_js_tts_speak: function (p_text, p_voice, p_volume, p_pitch, p_rate, p_utterance_id, p_callback) { - const func = GodotRuntime.get_func(p_callback); - - function listener_end(evt) { - evt.currentTarget.cb(1 /*TTS_UTTERANCE_ENDED*/, evt.currentTarget.id, 0); - } - - function listener_start(evt) { - evt.currentTarget.cb(0 /*TTS_UTTERANCE_STARTED*/, evt.currentTarget.id, 0); - } - - function listener_error(evt) { - evt.currentTarget.cb(2 /*TTS_UTTERANCE_CANCELED*/, evt.currentTarget.id, 0); - } - - function listener_bound(evt) { - evt.currentTarget.cb(3 /*TTS_UTTERANCE_BOUNDARY*/, evt.currentTarget.id, evt.charIndex); - } - - const utterance = new SpeechSynthesisUtterance(GodotRuntime.parseString(p_text)); - utterance.rate = p_rate; - utterance.pitch = p_pitch; - utterance.volume = p_volume / 100.0; - utterance.addEventListener('end', listener_end); - utterance.addEventListener('start', listener_start); - utterance.addEventListener('error', listener_error); - utterance.addEventListener('boundary', listener_bound); - utterance.id = p_utterance_id; - utterance.cb = func; - const voice = GodotRuntime.parseString(p_voice); - const voices = window.speechSynthesis.getVoices(); - for (let i = 0; i < voices.length; i++) { - if (voices[i].name === voice) { - utterance.voice = voices[i]; - break; - } - } - window.speechSynthesis.resume(); - window.speechSynthesis.speak(utterance); - }, - - godot_js_tts_pause__sig: 'v', - godot_js_tts_pause: function () { - window.speechSynthesis.pause(); - }, - - godot_js_tts_resume__sig: 'v', - godot_js_tts_resume: function () { - window.speechSynthesis.resume(); - }, - - godot_js_tts_stop__sig: 'v', - godot_js_tts_stop: function () { - window.speechSynthesis.cancel(); - window.speechSynthesis.resume(); - }, - - godot_js_display_alert__sig: 'vi', - godot_js_display_alert: function (p_text) { - window.alert(GodotRuntime.parseString(p_text)); // eslint-disable-line no-alert - }, - - godot_js_display_screen_dpi_get__sig: 'i', - godot_js_display_screen_dpi_get: function () { - return GodotDisplay.findDPI(); - }, - - godot_js_display_pixel_ratio_get__sig: 'f', - godot_js_display_pixel_ratio_get: function () { - return GodotDisplayScreen.getPixelRatio(); - }, - - godot_js_display_fullscreen_request__sig: 'i', - godot_js_display_fullscreen_request: function () { - return GodotDisplayScreen.requestFullscreen(); - }, - - godot_js_display_fullscreen_exit__sig: 'i', - godot_js_display_fullscreen_exit: function () { - return GodotDisplayScreen.exitFullscreen(); - }, - - godot_js_display_desired_size_set__sig: 'vii', - godot_js_display_desired_size_set: function (width, height) { - GodotDisplayScreen.desired_size = [width, height]; - GodotDisplayScreen.updateSize(); - }, - - godot_js_display_size_update__sig: 'i', - godot_js_display_size_update: function () { - const updated = GodotDisplayScreen.updateSize(); - if (updated) { - GodotDisplayVK.updateSize(); - } - return updated; - }, - - godot_js_display_screen_size_get__sig: 'vii', - godot_js_display_screen_size_get: function (width, height) { - const scale = GodotDisplayScreen.getPixelRatio(); - GodotRuntime.setHeapValue(width, window.screen.width * scale, 'i32'); - GodotRuntime.setHeapValue(height, window.screen.height * scale, 'i32'); - }, - - godot_js_display_window_size_get__sig: 'vii', - godot_js_display_window_size_get: function (p_width, p_height) { - GodotRuntime.setHeapValue(p_width, GodotConfig.canvas.width, 'i32'); - GodotRuntime.setHeapValue(p_height, GodotConfig.canvas.height, 'i32'); - }, - - godot_js_display_has_webgl__sig: 'ii', - godot_js_display_has_webgl: function (p_version) { - if (p_version !== 1 && p_version !== 2) { - return false; - } - try { - return !!document.createElement('canvas').getContext(p_version === 2 ? 'webgl2' : 'webgl'); - } catch (e) { /* Not available */ } - return false; - }, - - /* - * Canvas - */ - godot_js_display_canvas_focus__sig: 'v', - godot_js_display_canvas_focus: function () { - GodotConfig.canvas.focus(); - }, - - godot_js_display_canvas_is_focused__sig: 'i', - godot_js_display_canvas_is_focused: function () { - return document.activeElement === GodotConfig.canvas; - }, - - /* - * Touchscreen - */ - godot_js_display_touchscreen_is_available__sig: 'i', - godot_js_display_touchscreen_is_available: function () { - return 'ontouchstart' in window; - }, - - /* - * Clipboard - */ - godot_js_display_clipboard_set__sig: 'ii', - godot_js_display_clipboard_set: function (p_text) { - const text = GodotRuntime.parseString(p_text); - if (!navigator.clipboard || !navigator.clipboard.writeText) { - return 1; - } - navigator.clipboard.writeText(text).catch(function (e) { - // Setting OS clipboard is only possible from an input callback. - GodotRuntime.error('Setting OS clipboard is only possible from an input callback for the HTML5 plafrom. Exception:', e); - }); - return 0; - }, - - godot_js_display_clipboard_get__sig: 'ii', - godot_js_display_clipboard_get: function (callback) { - const func = GodotRuntime.get_func(callback); - try { - navigator.clipboard.readText().then(function (result) { - const ptr = GodotRuntime.allocString(result); - func(ptr); - GodotRuntime.free(ptr); - }).catch(function (e) { - // Fail graciously. - }); - } catch (e) { - // Fail graciously. - } - }, - - /* - * Window - */ - godot_js_display_window_title_set__sig: 'vi', - godot_js_display_window_title_set: function (p_data) { - document.title = GodotRuntime.parseString(p_data); - }, - - godot_js_display_window_icon_set__sig: 'vii', - godot_js_display_window_icon_set: function (p_ptr, p_len) { - let link = document.getElementById('-gd-engine-icon'); - if (link === null) { - link = document.createElement('link'); - link.rel = 'icon'; - link.id = '-gd-engine-icon'; - document.head.appendChild(link); - } - const old_icon = GodotDisplay.window_icon; - const png = new Blob([GodotRuntime.heapSlice(HEAPU8, p_ptr, p_len)], { type: 'image/png' }); - GodotDisplay.window_icon = URL.createObjectURL(png); - link.href = GodotDisplay.window_icon; - if (old_icon) { - URL.revokeObjectURL(old_icon); - } - }, - - /* - * Cursor - */ - godot_js_display_cursor_set_visible__sig: 'vi', - godot_js_display_cursor_set_visible: function (p_visible) { - const visible = p_visible !== 0; - if (visible === GodotDisplayCursor.visible) { - return; - } - GodotDisplayCursor.visible = visible; - if (visible) { - GodotDisplayCursor.set_shape(GodotDisplayCursor.shape); - } else { - GodotDisplayCursor.set_style('none'); - } - }, - - godot_js_display_cursor_is_hidden__sig: 'i', - godot_js_display_cursor_is_hidden: function () { - return !GodotDisplayCursor.visible; - }, - - godot_js_display_cursor_set_shape__sig: 'vi', - godot_js_display_cursor_set_shape: function (p_string) { - GodotDisplayCursor.set_shape(GodotRuntime.parseString(p_string)); - }, - - godot_js_display_cursor_set_custom_shape__sig: 'viiiii', - godot_js_display_cursor_set_custom_shape: function (p_shape, p_ptr, p_len, p_hotspot_x, p_hotspot_y) { - const shape = GodotRuntime.parseString(p_shape); - const old_shape = GodotDisplayCursor.cursors[shape]; - if (p_len > 0) { - const png = new Blob([GodotRuntime.heapSlice(HEAPU8, p_ptr, p_len)], { type: 'image/png' }); - const url = URL.createObjectURL(png); - GodotDisplayCursor.cursors[shape] = { - url: url, - x: p_hotspot_x, - y: p_hotspot_y, - }; - } else { - delete GodotDisplayCursor.cursors[shape]; - } - if (shape === GodotDisplayCursor.shape) { - GodotDisplayCursor.set_shape(GodotDisplayCursor.shape); - } - if (old_shape) { - URL.revokeObjectURL(old_shape.url); - } - }, - - godot_js_display_cursor_lock_set__sig: 'vi', - godot_js_display_cursor_lock_set: function (p_lock) { - if (p_lock) { - GodotDisplayCursor.lockPointer(); - } else { - GodotDisplayCursor.releasePointer(); - } - }, - - godot_js_display_cursor_is_locked__sig: 'i', - godot_js_display_cursor_is_locked: function () { - return GodotDisplayCursor.isPointerLocked() ? 1 : 0; - }, - - /* - * Listeners - */ - godot_js_display_fullscreen_cb__sig: 'vi', - godot_js_display_fullscreen_cb: function (callback) { - const canvas = GodotConfig.canvas; - const func = GodotRuntime.get_func(callback); - function change_cb(evt) { - if (evt.target === canvas) { - func(GodotDisplayScreen.isFullscreen()); - } - } - GodotEventListeners.add(document, 'fullscreenchange', change_cb, false); - GodotEventListeners.add(document, 'mozfullscreenchange', change_cb, false); - GodotEventListeners.add(document, 'webkitfullscreenchange', change_cb, false); - }, - - godot_js_display_window_blur_cb__sig: 'vi', - godot_js_display_window_blur_cb: function (callback) { - const func = GodotRuntime.get_func(callback); - GodotEventListeners.add(window, 'blur', function () { - func(); - }, false); - }, - - godot_js_display_notification_cb__sig: 'viiiii', - godot_js_display_notification_cb: function (callback, p_enter, p_exit, p_in, p_out) { - const canvas = GodotConfig.canvas; - const func = GodotRuntime.get_func(callback); - const notif = [p_enter, p_exit, p_in, p_out]; - ['mouseover', 'mouseleave', 'focus', 'blur'].forEach(function (evt_name, idx) { - GodotEventListeners.add(canvas, evt_name, function () { - func(notif[idx]); - }, true); - }); - }, - - godot_js_display_setup_canvas__sig: 'viiii', - godot_js_display_setup_canvas: function (p_width, p_height, p_fullscreen, p_hidpi) { - const canvas = GodotConfig.canvas; - GodotEventListeners.add(canvas, 'contextmenu', function (ev) { - ev.preventDefault(); - }, false); - GodotEventListeners.add(canvas, 'webglcontextlost', function (ev) { - alert('WebGL context lost, please reload the page'); // eslint-disable-line no-alert - ev.preventDefault(); - }, false); - GodotDisplayScreen.hidpi = !!p_hidpi; - switch (GodotConfig.canvas_resize_policy) { - case 0: // None - GodotDisplayScreen.desired_size = [canvas.width, canvas.height]; - break; - case 1: // Project - GodotDisplayScreen.desired_size = [p_width, p_height]; - break; - default: // Full window - // Ensure we display in the right place, the size will be handled by updateSize - canvas.style.position = 'absolute'; - canvas.style.top = 0; - canvas.style.left = 0; - break; - } - GodotDisplayScreen.updateSize(); - if (p_fullscreen) { - GodotDisplayScreen.requestFullscreen(); - } - }, - - /* - * Virtual Keyboard - */ - godot_js_display_vk_show__sig: 'viiii', - godot_js_display_vk_show: function (p_text, p_multiline, p_start, p_end) { - const text = GodotRuntime.parseString(p_text); - const start = p_start > 0 ? p_start : 0; - const end = p_end > 0 ? p_end : start; - GodotDisplayVK.show(text, p_multiline, start, end); - }, - - godot_js_display_vk_hide__sig: 'v', - godot_js_display_vk_hide: function () { - GodotDisplayVK.hide(); - }, - - godot_js_display_vk_available__sig: 'i', - godot_js_display_vk_available: function () { - return GodotDisplayVK.available(); - }, - - godot_js_display_tts_available__sig: 'i', - godot_js_display_tts_available: function () { - return 'speechSynthesis' in window; - }, - - godot_js_display_vk_cb__sig: 'vi', - godot_js_display_vk_cb: function (p_input_cb) { - const input_cb = GodotRuntime.get_func(p_input_cb); - if (GodotDisplayVK.available()) { - GodotDisplayVK.init(input_cb); - } - }, -}; - -autoAddDeps(GodotDisplay, '$GodotDisplay'); -mergeInto(LibraryManager.library, GodotDisplay); diff --git a/platform/javascript/js/libs/library_godot_fetch.js b/platform/javascript/js/libs/library_godot_fetch.js deleted file mode 100644 index 285e50a035..0000000000 --- a/platform/javascript/js/libs/library_godot_fetch.js +++ /dev/null @@ -1,247 +0,0 @@ -/*************************************************************************/ -/* library_godot_fetch.js */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -const GodotFetch = { - $GodotFetch__deps: ['$IDHandler', '$GodotRuntime'], - $GodotFetch: { - - onread: function (id, result) { - const obj = IDHandler.get(id); - if (!obj) { - return; - } - if (result.value) { - obj.chunks.push(result.value); - } - obj.reading = false; - obj.done = result.done; - }, - - onresponse: function (id, response) { - const obj = IDHandler.get(id); - if (!obj) { - return; - } - let chunked = false; - response.headers.forEach(function (value, header) { - const v = value.toLowerCase().trim(); - const h = header.toLowerCase().trim(); - if (h === 'transfer-encoding' && v === 'chunked') { - chunked = true; - } - }); - obj.status = response.status; - obj.response = response; - obj.reader = response.body.getReader(); - obj.chunked = chunked; - }, - - onerror: function (id, err) { - GodotRuntime.error(err); - const obj = IDHandler.get(id); - if (!obj) { - return; - } - obj.error = err; - }, - - create: function (method, url, headers, body) { - const obj = { - request: null, - response: null, - reader: null, - error: null, - done: false, - reading: false, - status: 0, - chunks: [], - bodySize: -1, - }; - const id = IDHandler.add(obj); - const init = { - method: method, - headers: headers, - body: body, - }; - obj.request = fetch(url, init); - obj.request.then(GodotFetch.onresponse.bind(null, id)).catch(GodotFetch.onerror.bind(null, id)); - return id; - }, - - free: function (id) { - const obj = IDHandler.get(id); - if (!obj) { - return; - } - IDHandler.remove(id); - if (!obj.request) { - return; - } - // Try to abort - obj.request.then(function (response) { - response.abort(); - }).catch(function (e) { /* nothing to do */ }); - }, - - read: function (id) { - const obj = IDHandler.get(id); - if (!obj) { - return; - } - if (obj.reader && !obj.reading) { - if (obj.done) { - obj.reader = null; - return; - } - obj.reading = true; - obj.reader.read().then(GodotFetch.onread.bind(null, id)).catch(GodotFetch.onerror.bind(null, id)); - } - }, - }, - - godot_js_fetch_create__sig: 'iiiiiii', - godot_js_fetch_create: function (p_method, p_url, p_headers, p_headers_size, p_body, p_body_size) { - const method = GodotRuntime.parseString(p_method); - const url = GodotRuntime.parseString(p_url); - const headers = GodotRuntime.parseStringArray(p_headers, p_headers_size); - const body = p_body_size ? GodotRuntime.heapSlice(HEAP8, p_body, p_body_size) : null; - return GodotFetch.create(method, url, headers.map(function (hv) { - const idx = hv.indexOf(':'); - if (idx <= 0) { - return []; - } - return [ - hv.slice(0, idx).trim(), - hv.slice(idx + 1).trim(), - ]; - }).filter(function (v) { - return v.length === 2; - }), body); - }, - - godot_js_fetch_state_get__sig: 'ii', - godot_js_fetch_state_get: function (p_id) { - const obj = IDHandler.get(p_id); - if (!obj) { - return -1; - } - if (obj.error) { - return -1; - } - if (!obj.response) { - return 0; - } - if (obj.reader) { - return 1; - } - if (obj.done) { - return 2; - } - return -1; - }, - - godot_js_fetch_http_status_get__sig: 'ii', - godot_js_fetch_http_status_get: function (p_id) { - const obj = IDHandler.get(p_id); - if (!obj || !obj.response) { - return 0; - } - return obj.status; - }, - - godot_js_fetch_read_headers__sig: 'iiii', - godot_js_fetch_read_headers: function (p_id, p_parse_cb, p_ref) { - const obj = IDHandler.get(p_id); - if (!obj || !obj.response) { - return 1; - } - const cb = GodotRuntime.get_func(p_parse_cb); - const arr = []; - obj.response.headers.forEach(function (v, h) { - arr.push(`${h}:${v}`); - }); - const c_ptr = GodotRuntime.allocStringArray(arr); - cb(arr.length, c_ptr, p_ref); - GodotRuntime.freeStringArray(c_ptr, arr.length); - return 0; - }, - - godot_js_fetch_read_chunk__sig: 'iiii', - godot_js_fetch_read_chunk: function (p_id, p_buf, p_buf_size) { - const obj = IDHandler.get(p_id); - if (!obj || !obj.response) { - return 0; - } - let to_read = p_buf_size; - const chunks = obj.chunks; - while (to_read && chunks.length) { - const chunk = obj.chunks[0]; - if (chunk.length > to_read) { - GodotRuntime.heapCopy(HEAP8, chunk.slice(0, to_read), p_buf); - chunks[0] = chunk.slice(to_read); - to_read = 0; - } else { - GodotRuntime.heapCopy(HEAP8, chunk, p_buf); - to_read -= chunk.length; - chunks.pop(); - } - } - if (!chunks.length) { - GodotFetch.read(p_id); - } - return p_buf_size - to_read; - }, - - godot_js_fetch_body_length_get__sig: 'ii', - godot_js_fetch_body_length_get: function (p_id) { - const obj = IDHandler.get(p_id); - if (!obj || !obj.response) { - return -1; - } - return obj.bodySize; - }, - - godot_js_fetch_is_chunked__sig: 'ii', - godot_js_fetch_is_chunked: function (p_id) { - const obj = IDHandler.get(p_id); - if (!obj || !obj.response) { - return -1; - } - return obj.chunked ? 1 : 0; - }, - - godot_js_fetch_free__sig: 'vi', - godot_js_fetch_free: function (id) { - GodotFetch.free(id); - }, -}; - -autoAddDeps(GodotFetch, '$GodotFetch'); -mergeInto(LibraryManager.library, GodotFetch); diff --git a/platform/javascript/js/libs/library_godot_input.js b/platform/javascript/js/libs/library_godot_input.js deleted file mode 100644 index 1e64c260f8..0000000000 --- a/platform/javascript/js/libs/library_godot_input.js +++ /dev/null @@ -1,540 +0,0 @@ -/*************************************************************************/ -/* library_godot_input.js */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -/* - * Gamepad API helper. - */ -const GodotInputGamepads = { - $GodotInputGamepads__deps: ['$GodotRuntime', '$GodotEventListeners'], - $GodotInputGamepads: { - samples: [], - - get_pads: function () { - try { - // Will throw in iframe when permission is denied. - // Will throw/warn in the future for insecure contexts. - // See https://github.com/w3c/gamepad/pull/120 - const pads = navigator.getGamepads(); - if (pads) { - return pads; - } - return []; - } catch (e) { - return []; - } - }, - - get_samples: function () { - return GodotInputGamepads.samples; - }, - - get_sample: function (index) { - const samples = GodotInputGamepads.samples; - return index < samples.length ? samples[index] : null; - }, - - sample: function () { - const pads = GodotInputGamepads.get_pads(); - const samples = []; - for (let i = 0; i < pads.length; i++) { - const pad = pads[i]; - if (!pad) { - samples.push(null); - continue; - } - const s = { - standard: pad.mapping === 'standard', - buttons: [], - axes: [], - connected: pad.connected, - }; - for (let b = 0; b < pad.buttons.length; b++) { - s.buttons.push(pad.buttons[b].value); - } - for (let a = 0; a < pad.axes.length; a++) { - s.axes.push(pad.axes[a]); - } - samples.push(s); - } - GodotInputGamepads.samples = samples; - }, - - init: function (onchange) { - GodotInputGamepads.samples = []; - function add(pad) { - const guid = GodotInputGamepads.get_guid(pad); - const c_id = GodotRuntime.allocString(pad.id); - const c_guid = GodotRuntime.allocString(guid); - onchange(pad.index, 1, c_id, c_guid); - GodotRuntime.free(c_id); - GodotRuntime.free(c_guid); - } - const pads = GodotInputGamepads.get_pads(); - for (let i = 0; i < pads.length; i++) { - // Might be reserved space. - if (pads[i]) { - add(pads[i]); - } - } - GodotEventListeners.add(window, 'gamepadconnected', function (evt) { - if (evt.gamepad) { - add(evt.gamepad); - } - }, false); - GodotEventListeners.add(window, 'gamepaddisconnected', function (evt) { - if (evt.gamepad) { - onchange(evt.gamepad.index, 0); - } - }, false); - }, - - get_guid: function (pad) { - if (pad.mapping) { - return pad.mapping; - } - const ua = navigator.userAgent; - let os = 'Unknown'; - if (ua.indexOf('Android') >= 0) { - os = 'Android'; - } else if (ua.indexOf('Linux') >= 0) { - os = 'Linux'; - } else if (ua.indexOf('iPhone') >= 0) { - os = 'iOS'; - } else if (ua.indexOf('Macintosh') >= 0) { - // Updated iPads will fall into this category. - os = 'MacOSX'; - } else if (ua.indexOf('Windows') >= 0) { - os = 'Windows'; - } - - const id = pad.id; - // Chrom* style: NAME (Vendor: xxxx Product: xxxx) - const exp1 = /vendor: ([0-9a-f]{4}) product: ([0-9a-f]{4})/i; - // Firefox/Safari style (safari may remove leading zeores) - const exp2 = /^([0-9a-f]+)-([0-9a-f]+)-/i; - let vendor = ''; - let product = ''; - if (exp1.test(id)) { - const match = exp1.exec(id); - vendor = match[1].padStart(4, '0'); - product = match[2].padStart(4, '0'); - } else if (exp2.test(id)) { - const match = exp2.exec(id); - vendor = match[1].padStart(4, '0'); - product = match[2].padStart(4, '0'); - } - if (!vendor || !product) { - return `${os}Unknown`; - } - return os + vendor + product; - }, - }, -}; -mergeInto(LibraryManager.library, GodotInputGamepads); - -/* - * Drag and drop helper. - * This is pretty big, but basically detect dropped files on GodotConfig.canvas, - * process them one by one (recursively for directories), and copies them to - * the temporary FS path '/tmp/drop-[random]/' so it can be emitted as a godot - * event (that requires a string array of paths). - * - * NOTE: The temporary files are removed after the callback. This means that - * deferred callbacks won't be able to access the files. - */ -const GodotInputDragDrop = { - $GodotInputDragDrop__deps: ['$FS', '$GodotFS'], - $GodotInputDragDrop: { - promises: [], - pending_files: [], - - add_entry: function (entry) { - if (entry.isDirectory) { - GodotInputDragDrop.add_dir(entry); - } else if (entry.isFile) { - GodotInputDragDrop.add_file(entry); - } else { - GodotRuntime.error('Unrecognized entry...', entry); - } - }, - - add_dir: function (entry) { - GodotInputDragDrop.promises.push(new Promise(function (resolve, reject) { - const reader = entry.createReader(); - reader.readEntries(function (entries) { - for (let i = 0; i < entries.length; i++) { - GodotInputDragDrop.add_entry(entries[i]); - } - resolve(); - }); - })); - }, - - add_file: function (entry) { - GodotInputDragDrop.promises.push(new Promise(function (resolve, reject) { - entry.file(function (file) { - const reader = new FileReader(); - reader.onload = function () { - const f = { - 'path': file.relativePath || file.webkitRelativePath, - 'name': file.name, - 'type': file.type, - 'size': file.size, - 'data': reader.result, - }; - if (!f['path']) { - f['path'] = f['name']; - } - GodotInputDragDrop.pending_files.push(f); - resolve(); - }; - reader.onerror = function () { - GodotRuntime.print('Error reading file'); - reject(); - }; - reader.readAsArrayBuffer(file); - }, function (err) { - GodotRuntime.print('Error!'); - reject(); - }); - })); - }, - - process: function (resolve, reject) { - if (GodotInputDragDrop.promises.length === 0) { - resolve(); - return; - } - GodotInputDragDrop.promises.pop().then(function () { - setTimeout(function () { - GodotInputDragDrop.process(resolve, reject); - }, 0); - }); - }, - - _process_event: function (ev, callback) { - ev.preventDefault(); - if (ev.dataTransfer.items) { - // Use DataTransferItemList interface to access the file(s) - for (let i = 0; i < ev.dataTransfer.items.length; i++) { - const item = ev.dataTransfer.items[i]; - let entry = null; - if ('getAsEntry' in item) { - entry = item.getAsEntry(); - } else if ('webkitGetAsEntry' in item) { - entry = item.webkitGetAsEntry(); - } - if (entry) { - GodotInputDragDrop.add_entry(entry); - } - } - } else { - GodotRuntime.error('File upload not supported'); - } - new Promise(GodotInputDragDrop.process).then(function () { - const DROP = `/tmp/drop-${parseInt(Math.random() * (1 << 30), 10)}/`; - const drops = []; - const files = []; - FS.mkdir(DROP.slice(0, -1)); // Without trailing slash - GodotInputDragDrop.pending_files.forEach((elem) => { - const path = elem['path']; - GodotFS.copy_to_fs(DROP + path, elem['data']); - let idx = path.indexOf('/'); - if (idx === -1) { - // Root file - drops.push(DROP + path); - } else { - // Subdir - const sub = path.substr(0, idx); - idx = sub.indexOf('/'); - if (idx < 0 && drops.indexOf(DROP + sub) === -1) { - drops.push(DROP + sub); - } - } - files.push(DROP + path); - }); - GodotInputDragDrop.promises = []; - GodotInputDragDrop.pending_files = []; - callback(drops); - if (GodotConfig.persistent_drops) { - // Delay removal at exit. - GodotOS.atexit(function (resolve, reject) { - GodotInputDragDrop.remove_drop(files, DROP); - resolve(); - }); - } else { - GodotInputDragDrop.remove_drop(files, DROP); - } - }); - }, - - remove_drop: function (files, drop_path) { - const dirs = [drop_path.substr(0, drop_path.length - 1)]; - // Remove temporary files - files.forEach(function (file) { - FS.unlink(file); - let dir = file.replace(drop_path, ''); - let idx = dir.lastIndexOf('/'); - while (idx > 0) { - dir = dir.substr(0, idx); - if (dirs.indexOf(drop_path + dir) === -1) { - dirs.push(drop_path + dir); - } - idx = dir.lastIndexOf('/'); - } - }); - // Remove dirs. - dirs.sort(function (a, b) { - const al = (a.match(/\//g) || []).length; - const bl = (b.match(/\//g) || []).length; - if (al > bl) { - return -1; - } else if (al < bl) { - return 1; - } - return 0; - }).forEach(function (dir) { - FS.rmdir(dir); - }); - }, - - handler: function (callback) { - return function (ev) { - GodotInputDragDrop._process_event(ev, callback); - }; - }, - }, -}; -mergeInto(LibraryManager.library, GodotInputDragDrop); - -/* - * Godot exposed input functions. - */ -const GodotInput = { - $GodotInput__deps: ['$GodotRuntime', '$GodotConfig', '$GodotEventListeners', '$GodotInputGamepads', '$GodotInputDragDrop'], - $GodotInput: { - getModifiers: function (evt) { - return (evt.shiftKey + 0) + ((evt.altKey + 0) << 1) + ((evt.ctrlKey + 0) << 2) + ((evt.metaKey + 0) << 3); - }, - computePosition: function (evt, rect) { - const canvas = GodotConfig.canvas; - const rw = canvas.width / rect.width; - const rh = canvas.height / rect.height; - const x = (evt.clientX - rect.x) * rw; - const y = (evt.clientY - rect.y) * rh; - return [x, y]; - }, - }, - - /* - * Mouse API - */ - godot_js_input_mouse_move_cb__sig: 'vi', - godot_js_input_mouse_move_cb: function (callback) { - const func = GodotRuntime.get_func(callback); - const canvas = GodotConfig.canvas; - function move_cb(evt) { - const rect = canvas.getBoundingClientRect(); - const pos = GodotInput.computePosition(evt, rect); - // Scale movement - const rw = canvas.width / rect.width; - const rh = canvas.height / rect.height; - const rel_pos_x = evt.movementX * rw; - const rel_pos_y = evt.movementY * rh; - const modifiers = GodotInput.getModifiers(evt); - func(pos[0], pos[1], rel_pos_x, rel_pos_y, modifiers); - } - GodotEventListeners.add(window, 'mousemove', move_cb, false); - }, - - godot_js_input_mouse_wheel_cb__sig: 'vi', - godot_js_input_mouse_wheel_cb: function (callback) { - const func = GodotRuntime.get_func(callback); - function wheel_cb(evt) { - if (func(evt['deltaX'] || 0, evt['deltaY'] || 0)) { - evt.preventDefault(); - } - } - GodotEventListeners.add(GodotConfig.canvas, 'wheel', wheel_cb, false); - }, - - godot_js_input_mouse_button_cb__sig: 'vi', - godot_js_input_mouse_button_cb: function (callback) { - const func = GodotRuntime.get_func(callback); - const canvas = GodotConfig.canvas; - function button_cb(p_pressed, evt) { - const rect = canvas.getBoundingClientRect(); - const pos = GodotInput.computePosition(evt, rect); - const modifiers = GodotInput.getModifiers(evt); - // Since the event is consumed, focus manually. - // NOTE: The iframe container may not have focus yet, so focus even when already active. - if (p_pressed) { - GodotConfig.canvas.focus(); - } - if (func(p_pressed, evt.button, pos[0], pos[1], modifiers)) { - evt.preventDefault(); - } - } - GodotEventListeners.add(canvas, 'mousedown', button_cb.bind(null, 1), false); - GodotEventListeners.add(window, 'mouseup', button_cb.bind(null, 0), false); - }, - - /* - * Touch API - */ - godot_js_input_touch_cb__sig: 'viii', - godot_js_input_touch_cb: function (callback, ids, coords) { - const func = GodotRuntime.get_func(callback); - const canvas = GodotConfig.canvas; - function touch_cb(type, evt) { - // Since the event is consumed, focus manually. - // NOTE: The iframe container may not have focus yet, so focus even when already active. - if (type === 0) { - GodotConfig.canvas.focus(); - } - const rect = canvas.getBoundingClientRect(); - const touches = evt.changedTouches; - for (let i = 0; i < touches.length; i++) { - const touch = touches[i]; - const pos = GodotInput.computePosition(touch, rect); - GodotRuntime.setHeapValue(coords + (i * 2) * 8, pos[0], 'double'); - GodotRuntime.setHeapValue(coords + (i * 2 + 1) * 8, pos[1], 'double'); - GodotRuntime.setHeapValue(ids + i * 4, touch.identifier, 'i32'); - } - func(type, touches.length); - if (evt.cancelable) { - evt.preventDefault(); - } - } - GodotEventListeners.add(canvas, 'touchstart', touch_cb.bind(null, 0), false); - GodotEventListeners.add(canvas, 'touchend', touch_cb.bind(null, 1), false); - GodotEventListeners.add(canvas, 'touchcancel', touch_cb.bind(null, 1), false); - GodotEventListeners.add(canvas, 'touchmove', touch_cb.bind(null, 2), false); - }, - - /* - * Key API - */ - godot_js_input_key_cb__sig: 'viii', - godot_js_input_key_cb: function (callback, code, key) { - const func = GodotRuntime.get_func(callback); - function key_cb(pressed, evt) { - const modifiers = GodotInput.getModifiers(evt); - GodotRuntime.stringToHeap(evt.code, code, 32); - GodotRuntime.stringToHeap(evt.key, key, 32); - func(pressed, evt.repeat, modifiers); - evt.preventDefault(); - } - GodotEventListeners.add(GodotConfig.canvas, 'keydown', key_cb.bind(null, 1), false); - GodotEventListeners.add(GodotConfig.canvas, 'keyup', key_cb.bind(null, 0), false); - }, - - /* - * Gamepad API - */ - godot_js_input_gamepad_cb__sig: 'vi', - godot_js_input_gamepad_cb: function (change_cb) { - const onchange = GodotRuntime.get_func(change_cb); - GodotInputGamepads.init(onchange); - }, - - godot_js_input_gamepad_sample_count__sig: 'i', - godot_js_input_gamepad_sample_count: function () { - return GodotInputGamepads.get_samples().length; - }, - - godot_js_input_gamepad_sample__sig: 'i', - godot_js_input_gamepad_sample: function () { - GodotInputGamepads.sample(); - return 0; - }, - - godot_js_input_gamepad_sample_get__sig: 'iiiiiii', - godot_js_input_gamepad_sample_get: function (p_index, r_btns, r_btns_num, r_axes, r_axes_num, r_standard) { - const sample = GodotInputGamepads.get_sample(p_index); - if (!sample || !sample.connected) { - return 1; - } - const btns = sample.buttons; - const btns_len = btns.length < 16 ? btns.length : 16; - for (let i = 0; i < btns_len; i++) { - GodotRuntime.setHeapValue(r_btns + (i << 2), btns[i], 'float'); - } - GodotRuntime.setHeapValue(r_btns_num, btns_len, 'i32'); - const axes = sample.axes; - const axes_len = axes.length < 10 ? axes.length : 10; - for (let i = 0; i < axes_len; i++) { - GodotRuntime.setHeapValue(r_axes + (i << 2), axes[i], 'float'); - } - GodotRuntime.setHeapValue(r_axes_num, axes_len, 'i32'); - const is_standard = sample.standard ? 1 : 0; - GodotRuntime.setHeapValue(r_standard, is_standard, 'i32'); - return 0; - }, - - /* - * Drag/Drop API - */ - godot_js_input_drop_files_cb__sig: 'vi', - godot_js_input_drop_files_cb: function (callback) { - const func = GodotRuntime.get_func(callback); - const dropFiles = function (files) { - const args = files || []; - if (!args.length) { - return; - } - const argc = args.length; - const argv = GodotRuntime.allocStringArray(args); - func(argv, argc); - GodotRuntime.freeStringArray(argv, argc); - }; - const canvas = GodotConfig.canvas; - GodotEventListeners.add(canvas, 'dragover', function (ev) { - // Prevent default behavior (which would try to open the file(s)) - ev.preventDefault(); - }, false); - GodotEventListeners.add(canvas, 'drop', GodotInputDragDrop.handler(dropFiles)); - }, - - /* Paste API */ - godot_js_input_paste_cb__sig: 'vi', - godot_js_input_paste_cb: function (callback) { - const func = GodotRuntime.get_func(callback); - GodotEventListeners.add(window, 'paste', function (evt) { - const text = evt.clipboardData.getData('text'); - const ptr = GodotRuntime.allocString(text); - func(ptr); - GodotRuntime.free(ptr); - }, false); - }, -}; - -autoAddDeps(GodotInput, '$GodotInput'); -mergeInto(LibraryManager.library, GodotInput); diff --git a/platform/javascript/js/libs/library_godot_javascript_singleton.js b/platform/javascript/js/libs/library_godot_javascript_singleton.js deleted file mode 100644 index 692f27676a..0000000000 --- a/platform/javascript/js/libs/library_godot_javascript_singleton.js +++ /dev/null @@ -1,346 +0,0 @@ -/*************************************************************************/ -/* library_godot_eval.js */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -const GodotJSWrapper = { - - $GodotJSWrapper__deps: ['$GodotRuntime', '$IDHandler'], - $GodotJSWrapper__postset: 'GodotJSWrapper.proxies = new Map();', - $GodotJSWrapper: { - proxies: null, - cb_ret: null, - - MyProxy: function (val) { - const id = IDHandler.add(this); - GodotJSWrapper.proxies.set(val, id); - let refs = 1; - this.ref = function () { - refs++; - }; - this.unref = function () { - refs--; - if (refs === 0) { - IDHandler.remove(id); - GodotJSWrapper.proxies.delete(val); - } - }; - this.get_val = function () { - return val; - }; - this.get_id = function () { - return id; - }; - }, - - get_proxied: function (val) { - const id = GodotJSWrapper.proxies.get(val); - if (id === undefined) { - const proxy = new GodotJSWrapper.MyProxy(val); - return proxy.get_id(); - } - IDHandler.get(id).ref(); - return id; - }, - - get_proxied_value: function (id) { - const proxy = IDHandler.get(id); - if (proxy === undefined) { - return undefined; - } - return proxy.get_val(); - }, - - variant2js: function (type, val) { - switch (type) { - case 0: - return null; - case 1: - return !!GodotRuntime.getHeapValue(val, 'i64'); - case 2: - return GodotRuntime.getHeapValue(val, 'i64'); - case 3: - return GodotRuntime.getHeapValue(val, 'double'); - case 4: - return GodotRuntime.parseString(GodotRuntime.getHeapValue(val, '*')); - case 21: // OBJECT - return GodotJSWrapper.get_proxied_value(GodotRuntime.getHeapValue(val, 'i64')); - default: - return undefined; - } - }, - - js2variant: function (p_val, p_exchange) { - if (p_val === undefined || p_val === null) { - return 0; // NIL - } - const type = typeof (p_val); - if (type === 'boolean') { - GodotRuntime.setHeapValue(p_exchange, p_val, 'i64'); - return 1; // BOOL - } else if (type === 'number') { - if (Number.isInteger(p_val)) { - GodotRuntime.setHeapValue(p_exchange, p_val, 'i64'); - return 2; // INT - } - GodotRuntime.setHeapValue(p_exchange, p_val, 'double'); - return 3; // REAL - } else if (type === 'string') { - const c_str = GodotRuntime.allocString(p_val); - GodotRuntime.setHeapValue(p_exchange, c_str, '*'); - return 4; // STRING - } - const id = GodotJSWrapper.get_proxied(p_val); - GodotRuntime.setHeapValue(p_exchange, id, 'i64'); - return 21; - }, - }, - - godot_js_wrapper_interface_get__sig: 'ii', - godot_js_wrapper_interface_get: function (p_name) { - const name = GodotRuntime.parseString(p_name); - if (typeof (window[name]) !== 'undefined') { - return GodotJSWrapper.get_proxied(window[name]); - } - return 0; - }, - - godot_js_wrapper_object_get__sig: 'iiii', - godot_js_wrapper_object_get: function (p_id, p_exchange, p_prop) { - const obj = GodotJSWrapper.get_proxied_value(p_id); - if (obj === undefined) { - return 0; - } - if (p_prop) { - const prop = GodotRuntime.parseString(p_prop); - try { - return GodotJSWrapper.js2variant(obj[prop], p_exchange); - } catch (e) { - GodotRuntime.error(`Error getting variable ${prop} on object`, obj); - return 0; // NIL - } - } - return GodotJSWrapper.js2variant(obj, p_exchange); - }, - - godot_js_wrapper_object_set__sig: 'viiii', - godot_js_wrapper_object_set: function (p_id, p_name, p_type, p_exchange) { - const obj = GodotJSWrapper.get_proxied_value(p_id); - if (obj === undefined) { - return; - } - const name = GodotRuntime.parseString(p_name); - try { - obj[name] = GodotJSWrapper.variant2js(p_type, p_exchange); - } catch (e) { - GodotRuntime.error(`Error setting variable ${name} on object`, obj); - } - }, - - godot_js_wrapper_object_call__sig: 'iiiiiiiii', - godot_js_wrapper_object_call: function (p_id, p_method, p_args, p_argc, p_convert_callback, p_exchange, p_lock, p_free_lock_callback) { - const obj = GodotJSWrapper.get_proxied_value(p_id); - if (obj === undefined) { - return -1; - } - const method = GodotRuntime.parseString(p_method); - const convert = GodotRuntime.get_func(p_convert_callback); - const freeLock = GodotRuntime.get_func(p_free_lock_callback); - const args = new Array(p_argc); - for (let i = 0; i < p_argc; i++) { - const type = convert(p_args, i, p_exchange, p_lock); - const lock = GodotRuntime.getHeapValue(p_lock, '*'); - args[i] = GodotJSWrapper.variant2js(type, p_exchange); - if (lock) { - freeLock(p_lock, type); - } - } - try { - const res = obj[method](...args); - return GodotJSWrapper.js2variant(res, p_exchange); - } catch (e) { - GodotRuntime.error(`Error calling method ${method} on:`, obj, 'error:', e); - return -1; - } - }, - - godot_js_wrapper_object_unref__sig: 'vi', - godot_js_wrapper_object_unref: function (p_id) { - const proxy = IDHandler.get(p_id); - if (proxy !== undefined) { - proxy.unref(); - } - }, - - godot_js_wrapper_create_cb__sig: 'iii', - godot_js_wrapper_create_cb: function (p_ref, p_func) { - const func = GodotRuntime.get_func(p_func); - let id = 0; - const cb = function () { - if (!GodotJSWrapper.get_proxied_value(id)) { - return undefined; - } - // The callback will store the returned value in this variable via - // "godot_js_wrapper_object_set_cb_ret" upon calling the user function. - // This is safe! JavaScript is single threaded (and using it in threads is not a good idea anyway). - GodotJSWrapper.cb_ret = null; - const args = Array.from(arguments); - func(p_ref, GodotJSWrapper.get_proxied(args), args.length); - const ret = GodotJSWrapper.cb_ret; - GodotJSWrapper.cb_ret = null; - return ret; - }; - id = GodotJSWrapper.get_proxied(cb); - return id; - }, - - godot_js_wrapper_object_set_cb_ret__sig: 'vii', - godot_js_wrapper_object_set_cb_ret: function (p_val_type, p_val_ex) { - GodotJSWrapper.cb_ret = GodotJSWrapper.variant2js(p_val_type, p_val_ex); - }, - - godot_js_wrapper_object_getvar__sig: 'iiii', - godot_js_wrapper_object_getvar: function (p_id, p_type, p_exchange) { - const obj = GodotJSWrapper.get_proxied_value(p_id); - if (obj === undefined) { - return -1; - } - const prop = GodotJSWrapper.variant2js(p_type, p_exchange); - if (prop === undefined || prop === null) { - return -1; - } - try { - return GodotJSWrapper.js2variant(obj[prop], p_exchange); - } catch (e) { - GodotRuntime.error(`Error getting variable ${prop} on object`, obj, e); - return -1; - } - }, - - godot_js_wrapper_object_setvar__sig: 'iiiiii', - godot_js_wrapper_object_setvar: function (p_id, p_key_type, p_key_ex, p_val_type, p_val_ex) { - const obj = GodotJSWrapper.get_proxied_value(p_id); - if (obj === undefined) { - return -1; - } - const key = GodotJSWrapper.variant2js(p_key_type, p_key_ex); - try { - obj[key] = GodotJSWrapper.variant2js(p_val_type, p_val_ex); - return 0; - } catch (e) { - GodotRuntime.error(`Error setting variable ${key} on object`, obj); - return -1; - } - }, - - godot_js_wrapper_create_object__sig: 'iiiiiiii', - godot_js_wrapper_create_object: function (p_object, p_args, p_argc, p_convert_callback, p_exchange, p_lock, p_free_lock_callback) { - const name = GodotRuntime.parseString(p_object); - if (typeof (window[name]) === 'undefined') { - return -1; - } - const convert = GodotRuntime.get_func(p_convert_callback); - const freeLock = GodotRuntime.get_func(p_free_lock_callback); - const args = new Array(p_argc); - for (let i = 0; i < p_argc; i++) { - const type = convert(p_args, i, p_exchange, p_lock); - const lock = GodotRuntime.getHeapValue(p_lock, '*'); - args[i] = GodotJSWrapper.variant2js(type, p_exchange); - if (lock) { - freeLock(p_lock, type); - } - } - try { - const res = new window[name](...args); - return GodotJSWrapper.js2variant(res, p_exchange); - } catch (e) { - GodotRuntime.error(`Error calling constructor ${name} with args:`, args, 'error:', e); - return -1; - } - }, -}; - -autoAddDeps(GodotJSWrapper, '$GodotJSWrapper'); -mergeInto(LibraryManager.library, GodotJSWrapper); - -const GodotEval = { - godot_js_eval__deps: ['$GodotRuntime'], - godot_js_eval__sig: 'iiiiiii', - godot_js_eval: function (p_js, p_use_global_ctx, p_union_ptr, p_byte_arr, p_byte_arr_write, p_callback) { - const js_code = GodotRuntime.parseString(p_js); - let eval_ret = null; - try { - if (p_use_global_ctx) { - // indirect eval call grants global execution context - const global_eval = eval; // eslint-disable-line no-eval - eval_ret = global_eval(js_code); - } else { - eval_ret = eval(js_code); // eslint-disable-line no-eval - } - } catch (e) { - GodotRuntime.error(e); - } - - switch (typeof eval_ret) { - case 'boolean': - GodotRuntime.setHeapValue(p_union_ptr, eval_ret, 'i32'); - return 1; // BOOL - - case 'number': - GodotRuntime.setHeapValue(p_union_ptr, eval_ret, 'double'); - return 3; // REAL - - case 'string': - GodotRuntime.setHeapValue(p_union_ptr, GodotRuntime.allocString(eval_ret), '*'); - return 4; // STRING - - case 'object': - if (eval_ret === null) { - break; - } - - if (ArrayBuffer.isView(eval_ret) && !(eval_ret instanceof Uint8Array)) { - eval_ret = new Uint8Array(eval_ret.buffer); - } else if (eval_ret instanceof ArrayBuffer) { - eval_ret = new Uint8Array(eval_ret); - } - if (eval_ret instanceof Uint8Array) { - const func = GodotRuntime.get_func(p_callback); - const bytes_ptr = func(p_byte_arr, p_byte_arr_write, eval_ret.length); - HEAPU8.set(eval_ret, bytes_ptr); - return 20; // POOL_BYTE_ARRAY - } - break; - - // no default - } - return 0; // NIL - }, -}; - -mergeInto(LibraryManager.library, GodotEval); diff --git a/platform/javascript/js/libs/library_godot_os.js b/platform/javascript/js/libs/library_godot_os.js deleted file mode 100644 index 377eec3234..0000000000 --- a/platform/javascript/js/libs/library_godot_os.js +++ /dev/null @@ -1,427 +0,0 @@ -/*************************************************************************/ -/* library_godot_os.js */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -const IDHandler = { - $IDHandler: { - _last_id: 0, - _references: {}, - - get: function (p_id) { - return IDHandler._references[p_id]; - }, - - add: function (p_data) { - const id = ++IDHandler._last_id; - IDHandler._references[id] = p_data; - return id; - }, - - remove: function (p_id) { - delete IDHandler._references[p_id]; - }, - }, -}; - -autoAddDeps(IDHandler, '$IDHandler'); -mergeInto(LibraryManager.library, IDHandler); - -const GodotConfig = { - $GodotConfig__postset: 'Module["initConfig"] = GodotConfig.init_config;', - $GodotConfig__deps: ['$GodotRuntime'], - $GodotConfig: { - canvas: null, - locale: 'en', - canvas_resize_policy: 2, // Adaptive - virtual_keyboard: false, - persistent_drops: false, - on_execute: null, - on_exit: null, - - init_config: function (p_opts) { - GodotConfig.canvas_resize_policy = p_opts['canvasResizePolicy']; - GodotConfig.canvas = p_opts['canvas']; - GodotConfig.locale = p_opts['locale'] || GodotConfig.locale; - GodotConfig.virtual_keyboard = p_opts['virtualKeyboard']; - GodotConfig.persistent_drops = !!p_opts['persistentDrops']; - GodotConfig.on_execute = p_opts['onExecute']; - GodotConfig.on_exit = p_opts['onExit']; - if (p_opts['focusCanvas']) { - GodotConfig.canvas.focus(); - } - }, - - locate_file: function (file) { - return Module['locateFile'](file); // eslint-disable-line no-undef - }, - clear: function () { - GodotConfig.canvas = null; - GodotConfig.locale = 'en'; - GodotConfig.canvas_resize_policy = 2; - GodotConfig.virtual_keyboard = false; - GodotConfig.persistent_drops = false; - GodotConfig.on_execute = null; - GodotConfig.on_exit = null; - }, - }, - - godot_js_config_canvas_id_get__sig: 'vii', - godot_js_config_canvas_id_get: function (p_ptr, p_ptr_max) { - GodotRuntime.stringToHeap(`#${GodotConfig.canvas.id}`, p_ptr, p_ptr_max); - }, - - godot_js_config_locale_get__sig: 'vii', - godot_js_config_locale_get: function (p_ptr, p_ptr_max) { - GodotRuntime.stringToHeap(GodotConfig.locale, p_ptr, p_ptr_max); - }, -}; - -autoAddDeps(GodotConfig, '$GodotConfig'); -mergeInto(LibraryManager.library, GodotConfig); - -const GodotFS = { - $GodotFS__deps: ['$ERRNO_CODES', '$FS', '$IDBFS', '$GodotRuntime'], - $GodotFS__postset: [ - 'Module["initFS"] = GodotFS.init;', - 'Module["copyToFS"] = GodotFS.copy_to_fs;', - ].join(''), - $GodotFS: { - _idbfs: false, - _syncing: false, - _mount_points: [], - - is_persistent: function () { - return GodotFS._idbfs ? 1 : 0; - }, - - // Initialize godot file system, setting up persistent paths. - // Returns a promise that resolves when the FS is ready. - // We keep track of mount_points, so that we can properly close the IDBFS - // since emscripten is not doing it by itself. (emscripten GH#12516). - init: function (persistentPaths) { - GodotFS._idbfs = false; - if (!Array.isArray(persistentPaths)) { - return Promise.reject(new Error('Persistent paths must be an array')); - } - if (!persistentPaths.length) { - return Promise.resolve(); - } - GodotFS._mount_points = persistentPaths.slice(); - - function createRecursive(dir) { - try { - FS.stat(dir); - } catch (e) { - if (e.errno !== ERRNO_CODES.ENOENT) { - throw e; - } - FS.mkdirTree(dir); - } - } - - GodotFS._mount_points.forEach(function (path) { - createRecursive(path); - FS.mount(IDBFS, {}, path); - }); - return new Promise(function (resolve, reject) { - FS.syncfs(true, function (err) { - if (err) { - GodotFS._mount_points = []; - GodotFS._idbfs = false; - GodotRuntime.print(`IndexedDB not available: ${err.message}`); - } else { - GodotFS._idbfs = true; - } - resolve(err); - }); - }); - }, - - // Deinit godot file system, making sure to unmount file systems, and close IDBFS(s). - deinit: function () { - GodotFS._mount_points.forEach(function (path) { - try { - FS.unmount(path); - } catch (e) { - GodotRuntime.print('Already unmounted', e); - } - if (GodotFS._idbfs && IDBFS.dbs[path]) { - IDBFS.dbs[path].close(); - delete IDBFS.dbs[path]; - } - }); - GodotFS._mount_points = []; - GodotFS._idbfs = false; - GodotFS._syncing = false; - }, - - sync: function () { - if (GodotFS._syncing) { - GodotRuntime.error('Already syncing!'); - return Promise.resolve(); - } - GodotFS._syncing = true; - return new Promise(function (resolve, reject) { - FS.syncfs(false, function (error) { - if (error) { - GodotRuntime.error(`Failed to save IDB file system: ${error.message}`); - } - GodotFS._syncing = false; - resolve(error); - }); - }); - }, - - // Copies a buffer to the internal file system. Creating directories recursively. - copy_to_fs: function (path, buffer) { - const idx = path.lastIndexOf('/'); - let dir = '/'; - if (idx > 0) { - dir = path.slice(0, idx); - } - try { - FS.stat(dir); - } catch (e) { - if (e.errno !== ERRNO_CODES.ENOENT) { - throw e; - } - FS.mkdirTree(dir); - } - FS.writeFile(path, new Uint8Array(buffer)); - }, - }, -}; -mergeInto(LibraryManager.library, GodotFS); - -const GodotOS = { - $GodotOS__deps: ['$GodotRuntime', '$GodotConfig', '$GodotFS'], - $GodotOS__postset: [ - 'Module["request_quit"] = function() { GodotOS.request_quit() };', - 'Module["onExit"] = GodotOS.cleanup;', - 'GodotOS._fs_sync_promise = Promise.resolve();', - ].join(''), - $GodotOS: { - request_quit: function () {}, - _async_cbs: [], - _fs_sync_promise: null, - - atexit: function (p_promise_cb) { - GodotOS._async_cbs.push(p_promise_cb); - }, - - cleanup: function (exit_code) { - const cb = GodotConfig.on_exit; - GodotFS.deinit(); - GodotConfig.clear(); - if (cb) { - cb(exit_code); - } - }, - - finish_async: function (callback) { - GodotOS._fs_sync_promise.then(function (err) { - const promises = []; - GodotOS._async_cbs.forEach(function (cb) { - promises.push(new Promise(cb)); - }); - return Promise.all(promises); - }).then(function () { - return GodotFS.sync(); // Final FS sync. - }).then(function (err) { - // Always deferred. - setTimeout(function () { - callback(); - }, 0); - }); - }, - }, - - godot_js_os_finish_async__sig: 'vi', - godot_js_os_finish_async: function (p_callback) { - const func = GodotRuntime.get_func(p_callback); - GodotOS.finish_async(func); - }, - - godot_js_os_request_quit_cb__sig: 'vi', - godot_js_os_request_quit_cb: function (p_callback) { - GodotOS.request_quit = GodotRuntime.get_func(p_callback); - }, - - godot_js_os_fs_is_persistent__sig: 'i', - godot_js_os_fs_is_persistent: function () { - return GodotFS.is_persistent(); - }, - - godot_js_os_fs_sync__sig: 'vi', - godot_js_os_fs_sync: function (callback) { - const func = GodotRuntime.get_func(callback); - GodotOS._fs_sync_promise = GodotFS.sync(); - GodotOS._fs_sync_promise.then(function (err) { - func(); - }); - }, - - godot_js_os_execute__sig: 'ii', - godot_js_os_execute: function (p_json) { - const json_args = GodotRuntime.parseString(p_json); - const args = JSON.parse(json_args); - if (GodotConfig.on_execute) { - GodotConfig.on_execute(args); - return 0; - } - return 1; - }, - - godot_js_os_shell_open__sig: 'vi', - godot_js_os_shell_open: function (p_uri) { - window.open(GodotRuntime.parseString(p_uri), '_blank'); - }, - - godot_js_os_hw_concurrency_get__sig: 'i', - godot_js_os_hw_concurrency_get: function () { - // TODO Godot core needs fixing to avoid spawning too many threads (> 24). - const concurrency = navigator.hardwareConcurrency || 1; - return concurrency < 2 ? concurrency : 2; - }, - - godot_js_os_download_buffer__sig: 'viiii', - godot_js_os_download_buffer: function (p_ptr, p_size, p_name, p_mime) { - const buf = GodotRuntime.heapSlice(HEAP8, p_ptr, p_size); - const name = GodotRuntime.parseString(p_name); - const mime = GodotRuntime.parseString(p_mime); - const blob = new Blob([buf], { type: mime }); - const url = window.URL.createObjectURL(blob); - const a = document.createElement('a'); - a.href = url; - a.download = name; - a.style.display = 'none'; - document.body.appendChild(a); - a.click(); - a.remove(); - window.URL.revokeObjectURL(url); - }, -}; - -autoAddDeps(GodotOS, '$GodotOS'); -mergeInto(LibraryManager.library, GodotOS); - -/* - * Godot event listeners. - * Keeps track of registered event listeners so it can remove them on shutdown. - */ -const GodotEventListeners = { - $GodotEventListeners__deps: ['$GodotOS'], - $GodotEventListeners__postset: 'GodotOS.atexit(function(resolve, reject) { GodotEventListeners.clear(); resolve(); });', - $GodotEventListeners: { - handlers: [], - - has: function (target, event, method, capture) { - return GodotEventListeners.handlers.findIndex(function (e) { - return e.target === target && e.event === event && e.method === method && e.capture === capture; - }) !== -1; - }, - - add: function (target, event, method, capture) { - if (GodotEventListeners.has(target, event, method, capture)) { - return; - } - function Handler(p_target, p_event, p_method, p_capture) { - this.target = p_target; - this.event = p_event; - this.method = p_method; - this.capture = p_capture; - } - GodotEventListeners.handlers.push(new Handler(target, event, method, capture)); - target.addEventListener(event, method, capture); - }, - - clear: function () { - GodotEventListeners.handlers.forEach(function (h) { - h.target.removeEventListener(h.event, h.method, h.capture); - }); - GodotEventListeners.handlers.length = 0; - }, - }, -}; -mergeInto(LibraryManager.library, GodotEventListeners); - -const GodotPWA = { - - $GodotPWA__deps: ['$GodotRuntime', '$GodotEventListeners'], - $GodotPWA: { - hasUpdate: false, - - updateState: function (cb, reg) { - if (!reg) { - return; - } - if (!reg.active) { - return; - } - if (reg.waiting) { - GodotPWA.hasUpdate = true; - cb(); - } - GodotEventListeners.add(reg, 'updatefound', function () { - const installing = reg.installing; - GodotEventListeners.add(installing, 'statechange', function () { - if (installing.state === 'installed') { - GodotPWA.hasUpdate = true; - cb(); - } - }); - }); - }, - }, - - godot_js_pwa_cb__sig: 'vi', - godot_js_pwa_cb: function (p_update_cb) { - if ('serviceWorker' in navigator) { - const cb = GodotRuntime.get_func(p_update_cb); - navigator.serviceWorker.getRegistration().then(GodotPWA.updateState.bind(null, cb)); - } - }, - - godot_js_pwa_update__sig: 'i', - godot_js_pwa_update: function () { - if ('serviceWorker' in navigator && GodotPWA.hasUpdate) { - navigator.serviceWorker.getRegistration().then(function (reg) { - if (!reg || !reg.waiting) { - return; - } - reg.waiting.postMessage('update'); - }); - return 0; - } - return 1; - }, -}; - -autoAddDeps(GodotPWA, '$GodotPWA'); -mergeInto(LibraryManager.library, GodotPWA); diff --git a/platform/javascript/js/libs/library_godot_runtime.js b/platform/javascript/js/libs/library_godot_runtime.js deleted file mode 100644 index e2f7c8dca6..0000000000 --- a/platform/javascript/js/libs/library_godot_runtime.js +++ /dev/null @@ -1,134 +0,0 @@ -/*************************************************************************/ -/* library_godot_runtime.js */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -const GodotRuntime = { - $GodotRuntime: { - /* - * Functions - */ - get_func: function (ptr) { - return wasmTable.get(ptr); // eslint-disable-line no-undef - }, - - /* - * Prints - */ - error: function () { - err.apply(null, Array.from(arguments)); // eslint-disable-line no-undef - }, - - print: function () { - out.apply(null, Array.from(arguments)); // eslint-disable-line no-undef - }, - - /* - * Memory - */ - malloc: function (p_size) { - return _malloc(p_size); // eslint-disable-line no-undef - }, - - free: function (p_ptr) { - _free(p_ptr); // eslint-disable-line no-undef - }, - - getHeapValue: function (p_ptr, p_type) { - return getValue(p_ptr, p_type); // eslint-disable-line no-undef - }, - - setHeapValue: function (p_ptr, p_value, p_type) { - setValue(p_ptr, p_value, p_type); // eslint-disable-line no-undef - }, - - heapSub: function (p_heap, p_ptr, p_len) { - const bytes = p_heap.BYTES_PER_ELEMENT; - return p_heap.subarray(p_ptr / bytes, p_ptr / bytes + p_len); - }, - - heapSlice: function (p_heap, p_ptr, p_len) { - const bytes = p_heap.BYTES_PER_ELEMENT; - return p_heap.slice(p_ptr / bytes, p_ptr / bytes + p_len); - }, - - heapCopy: function (p_dst, p_src, p_ptr) { - const bytes = p_src.BYTES_PER_ELEMENT; - return p_dst.set(p_src, p_ptr / bytes); - }, - - /* - * Strings - */ - parseString: function (p_ptr) { - return UTF8ToString(p_ptr); // eslint-disable-line no-undef - }, - - parseStringArray: function (p_ptr, p_size) { - const strings = []; - const ptrs = GodotRuntime.heapSub(HEAP32, p_ptr, p_size); // TODO wasm64 - ptrs.forEach(function (ptr) { - strings.push(GodotRuntime.parseString(ptr)); - }); - return strings; - }, - - strlen: function (p_str) { - return lengthBytesUTF8(p_str); // eslint-disable-line no-undef - }, - - allocString: function (p_str) { - const length = GodotRuntime.strlen(p_str) + 1; - const c_str = GodotRuntime.malloc(length); - stringToUTF8(p_str, c_str, length); // eslint-disable-line no-undef - return c_str; - }, - - allocStringArray: function (p_strings) { - const size = p_strings.length; - const c_ptr = GodotRuntime.malloc(size * 4); - for (let i = 0; i < size; i++) { - HEAP32[(c_ptr >> 2) + i] = GodotRuntime.allocString(p_strings[i]); - } - return c_ptr; - }, - - freeStringArray: function (p_ptr, p_len) { - for (let i = 0; i < p_len; i++) { - GodotRuntime.free(HEAP32[(p_ptr >> 2) + i]); - } - GodotRuntime.free(p_ptr); - }, - - stringToHeap: function (p_str, p_ptr, p_len) { - return stringToUTF8Array(p_str, HEAP8, p_ptr, p_len); // eslint-disable-line no-undef - }, - }, -}; -autoAddDeps(GodotRuntime, '$GodotRuntime'); -mergeInto(LibraryManager.library, GodotRuntime); diff --git a/platform/javascript/logo.png b/platform/javascript/logo.png Binary files differdeleted file mode 100644 index c046d87dc4..0000000000 --- a/platform/javascript/logo.png +++ /dev/null diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp deleted file mode 100644 index 1686353229..0000000000 --- a/platform/javascript/os_javascript.cpp +++ /dev/null @@ -1,271 +0,0 @@ -/*************************************************************************/ -/* os_javascript.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "os_javascript.h" - -#include "core/debugger/engine_debugger.h" -#include "drivers/unix/dir_access_unix.h" -#include "drivers/unix/file_access_unix.h" -#include "main/main.h" -#include "platform/javascript/display_server_javascript.h" - -#include "modules/modules_enabled.gen.h" // For websocket. -#ifdef MODULE_WEBSOCKET_ENABLED -#include "modules/websocket/remote_debugger_peer_websocket.h" -#endif - -#include <dlfcn.h> -#include <emscripten.h> -#include <stdlib.h> - -#include "api/javascript_singleton.h" -#include "godot_js.h" - -void OS_JavaScript::alert(const String &p_alert, const String &p_title) { - godot_js_display_alert(p_alert.utf8().get_data()); -} - -// Lifecycle -void OS_JavaScript::initialize() { - OS_Unix::initialize_core(); - DisplayServerJavaScript::register_javascript_driver(); - -#ifdef MODULE_WEBSOCKET_ENABLED - EngineDebugger::register_uri_handler("ws://", RemoteDebuggerPeerWebSocket::create); - EngineDebugger::register_uri_handler("wss://", RemoteDebuggerPeerWebSocket::create); -#endif -} - -void OS_JavaScript::resume_audio() { - AudioDriverJavaScript::resume(); -} - -void OS_JavaScript::set_main_loop(MainLoop *p_main_loop) { - main_loop = p_main_loop; -} - -MainLoop *OS_JavaScript::get_main_loop() const { - return main_loop; -} - -void OS_JavaScript::fs_sync_callback() { - get_singleton()->idb_is_syncing = false; -} - -bool OS_JavaScript::main_loop_iterate() { - if (is_userfs_persistent() && idb_needs_sync && !idb_is_syncing) { - idb_is_syncing = true; - idb_needs_sync = false; - godot_js_os_fs_sync(&fs_sync_callback); - } - - DisplayServer::get_singleton()->process_events(); - - return Main::iteration(); -} - -void OS_JavaScript::delete_main_loop() { - if (main_loop) { - memdelete(main_loop); - } - main_loop = nullptr; -} - -void OS_JavaScript::finalize() { - delete_main_loop(); - for (AudioDriverJavaScript *driver : audio_drivers) { - memdelete(driver); - } - audio_drivers.clear(); -} - -// Miscellaneous - -Error OS_JavaScript::execute(const String &p_path, const List<String> &p_arguments, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex, bool p_open_console) { - return create_process(p_path, p_arguments); -} - -Error OS_JavaScript::create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id, bool p_open_console) { - Array args; - for (const String &E : p_arguments) { - args.push_back(E); - } - String json_args = Variant(args).to_json_string(); - int failed = godot_js_os_execute(json_args.utf8().get_data()); - ERR_FAIL_COND_V_MSG(failed, ERR_UNAVAILABLE, "OS::execute() or create_process() must be implemented in JavaScript via 'engine.setOnExecute' if required."); - return OK; -} - -Error OS_JavaScript::kill(const ProcessID &p_pid) { - ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "OS::kill() is not available on the HTML5 platform."); -} - -int OS_JavaScript::get_process_id() const { - ERR_FAIL_V_MSG(0, "OS::get_process_id() is not available on the HTML5 platform."); -} - -bool OS_JavaScript::is_process_running(const ProcessID &p_pid) const { - return false; -} - -int OS_JavaScript::get_processor_count() const { - return godot_js_os_hw_concurrency_get(); -} - -bool OS_JavaScript::_check_internal_feature_support(const String &p_feature) { - if (p_feature == "html5" || p_feature == "web") { - return true; - } - -#ifdef JAVASCRIPT_EVAL_ENABLED - if (p_feature == "javascript") { - return true; - } -#endif -#ifndef NO_THREADS - if (p_feature == "threads") { - return true; - } -#endif -#if WASM_GDNATIVE - if (p_feature == "wasm32") { - return true; - } -#endif - - return false; -} - -String OS_JavaScript::get_executable_path() const { - return OS::get_executable_path(); -} - -Error OS_JavaScript::shell_open(String p_uri) { - // Open URI in a new tab, browser will deal with it by protocol. - godot_js_os_shell_open(p_uri.utf8().get_data()); - return OK; -} - -String OS_JavaScript::get_name() const { - return "HTML5"; -} - -String OS_JavaScript::get_user_data_dir() const { - return "/userfs"; -} - -String OS_JavaScript::get_cache_path() const { - return "/home/web_user/.cache"; -} - -String OS_JavaScript::get_config_path() const { - return "/home/web_user/.config"; -} - -String OS_JavaScript::get_data_path() const { - return "/home/web_user/.local/share"; -} - -void OS_JavaScript::file_access_close_callback(const String &p_file, int p_flags) { - OS_JavaScript *os = OS_JavaScript::get_singleton(); - if (!(os->is_userfs_persistent() && (p_flags & FileAccess::WRITE))) { - return; // FS persistence is not working or we are not writing. - } - bool is_file_persistent = p_file.begins_with("/userfs"); -#ifdef TOOLS_ENABLED - // Hack for editor persistence (can we track). - is_file_persistent = is_file_persistent || p_file.begins_with("/home/web_user/"); -#endif - if (is_file_persistent) { - os->idb_needs_sync = true; - } -} - -void OS_JavaScript::update_pwa_state_callback() { - if (OS_JavaScript::get_singleton()) { - OS_JavaScript::get_singleton()->pwa_is_waiting = true; - } - if (JavaScript::get_singleton()) { - JavaScript::get_singleton()->emit_signal("pwa_update_available"); - } -} - -Error OS_JavaScript::pwa_update() { - return godot_js_pwa_update() ? FAILED : OK; -} - -bool OS_JavaScript::is_userfs_persistent() const { - return idb_available; -} - -Error OS_JavaScript::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) { - String path = p_path.get_file(); - p_library_handle = dlopen(path.utf8().get_data(), RTLD_NOW); - ERR_FAIL_COND_V_MSG(!p_library_handle, ERR_CANT_OPEN, "Can't open dynamic library: " + p_path + ". Error: " + dlerror()); - - if (r_resolved_path != nullptr) { - *r_resolved_path = path; - } - - return OK; -} - -OS_JavaScript *OS_JavaScript::get_singleton() { - return static_cast<OS_JavaScript *>(OS::get_singleton()); -} - -void OS_JavaScript::initialize_joypads() { -} - -OS_JavaScript::OS_JavaScript() { - char locale_ptr[16]; - godot_js_config_locale_get(locale_ptr, 16); - setenv("LANG", locale_ptr, true); - - godot_js_pwa_cb(&OS_JavaScript::update_pwa_state_callback); - - if (AudioDriverJavaScript::is_available()) { -#ifdef NO_THREADS - audio_drivers.push_back(memnew(AudioDriverScriptProcessor)); -#endif - audio_drivers.push_back(memnew(AudioDriverWorklet)); - } - for (int i = 0; i < audio_drivers.size(); i++) { - AudioDriverManager::add_driver(audio_drivers[i]); - } - - idb_available = godot_js_os_fs_is_persistent(); - - Vector<Logger *> loggers; - loggers.push_back(memnew(StdLogger)); - _set_logger(memnew(CompositeLogger(loggers))); - - FileAccessUnix::close_notification_func = file_access_close_callback; -} diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h deleted file mode 100644 index 0c672111cc..0000000000 --- a/platform/javascript/os_javascript.h +++ /dev/null @@ -1,110 +0,0 @@ -/*************************************************************************/ -/* os_javascript.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef OS_JAVASCRIPT_H -#define OS_JAVASCRIPT_H - -#include "audio_driver_javascript.h" -#include "core/input/input.h" -#include "drivers/unix/os_unix.h" -#include "servers/audio_server.h" - -#include <emscripten/html5.h> - -class OS_JavaScript : public OS_Unix { - MainLoop *main_loop = nullptr; - List<AudioDriverJavaScript *> audio_drivers; - - bool idb_is_syncing = false; - bool idb_available = false; - bool idb_needs_sync = false; - bool pwa_is_waiting = false; - - static void main_loop_callback(); - - static void file_access_close_callback(const String &p_file, int p_flags); - static void fs_sync_callback(); - static void update_pwa_state_callback(); - -protected: - void initialize() override; - - void set_main_loop(MainLoop *p_main_loop) override; - void delete_main_loop() override; - - void finalize() override; - - bool _check_internal_feature_support(const String &p_feature) override; - -public: - // Override return type to make writing static callbacks less tedious. - static OS_JavaScript *get_singleton(); - - bool pwa_needs_update() const { return pwa_is_waiting; } - Error pwa_update(); - - void initialize_joypads() override; - - MainLoop *get_main_loop() const override; - bool main_loop_iterate(); - - Error execute(const String &p_path, const List<String> &p_arguments, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr, bool p_open_console = false) override; - Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr, bool p_open_console = false) override; - Error kill(const ProcessID &p_pid) override; - int get_process_id() const override; - bool is_process_running(const ProcessID &p_pid) const override; - int get_processor_count() const override; - int get_default_thread_pool_size() const override { return 1; } - - String get_executable_path() const override; - Error shell_open(String p_uri) override; - String get_name() const override; - // Override default OS implementation which would block the main thread with delay_usec. - // Implemented in javascript_main.cpp loop callback instead. - void add_frame_delay(bool p_can_draw) override {} - - String get_cache_path() const override; - String get_config_path() const override; - String get_data_path() const override; - String get_user_data_dir() const override; - - bool is_userfs_persistent() const override; - bool is_single_window() const override { return true; } - - void alert(const String &p_alert, const String &p_title = "ALERT!") override; - - Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false, String *r_resolved_path = nullptr) override; - - void resume_audio(); - - OS_JavaScript(); -}; - -#endif diff --git a/platform/javascript/package-lock.json b/platform/javascript/package-lock.json deleted file mode 100644 index f72cde955a..0000000000 --- a/platform/javascript/package-lock.json +++ /dev/null @@ -1,5330 +0,0 @@ -{ - "name": "godot", - "version": "1.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "godot", - "version": "1.0.0", - "license": "MIT", - "devDependencies": { - "eslint": "^7.28.0", - "eslint-config-airbnb-base": "^14.2.1", - "eslint-plugin-import": "^2.23.4", - "jsdoc": "^3.6.7", - "serve": "^13.0.2" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", - "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.14.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.5.tgz", - "integrity": "sha512-TM8C+xtH/9n1qzX+JNHi7AN2zHMTiPUtspO0ZdHflW8KaskkALhMmuMHb4bCmNdv9VAPzJX3/bXqkVLnAvsPfg==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", - "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", - "dev": true - }, - "node_modules/@zeit/schemas": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.6.0.tgz", - "integrity": "sha512-uUrgZ8AxS+Lio0fZKAipJjAh415JyrOZowliZAzmnJSsf7piVL5w+G0+gFJ0KSu3QRhvui/7zuvpLz03YjXAhg==", - "dev": true - }, - "node_modules/accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "dev": true, - "dependencies": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "dev": true, - "dependencies": { - "string-width": "^4.1.0" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/arch": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", - "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/arg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arg/-/arg-2.0.0.tgz", - "integrity": "sha512-XxNTUzKnz1ctK3ZIcI2XUPlD96wbHP2nGqkPKpvk/HNRlPveYrXIVSTk9m3LcqOgDPg3B1nMvdV/K8wZd7PG4w==", - "dev": true - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/array-includes": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", - "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.5" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", - "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "node_modules/boxen": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", - "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", - "dev": true, - "dependencies": { - "ansi-align": "^3.0.0", - "camelcase": "^6.2.0", - "chalk": "^4.1.0", - "cli-boxes": "^2.2.1", - "string-width": "^4.2.2", - "type-fest": "^0.20.2", - "widest-line": "^3.1.0", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/catharsis": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", - "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", - "dev": true, - "dependencies": { - "lodash": "^4.17.15" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chalk/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/chalk/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/chalk/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/chalk/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/chalk/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-boxes": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/clipboardy": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-2.3.0.tgz", - "integrity": "sha512-mKhiIL2DrQIsuXMgBgnfEHOZOryC7kY7YO//TN6c63wlEm3NG5tz+YgY5rVi29KCmq/QQjKYvM7a19+MDOTHOQ==", - "dev": true, - "dependencies": { - "arch": "^2.1.1", - "execa": "^1.0.0", - "is-wsl": "^2.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dev": true, - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/compression": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.3.tgz", - "integrity": "sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==", - "dev": true, - "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.14", - "debug": "2.6.9", - "on-headers": "~1.0.1", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/compression/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/compression/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "node_modules/confusing-browser-globals": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.10.tgz", - "integrity": "sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA==", - "dev": true - }, - "node_modules/content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "node_modules/define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "dependencies": { - "object-keys": "^1.0.12" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/entities": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", - "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", - "dev": true - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-abstract": { - "version": "1.18.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", - "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "is-callable": "^1.2.3", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.3", - "is-string": "^1.0.6", - "object-inspect": "^1.10.3", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.28.0.tgz", - "integrity": "sha512-UMfH0VSjP0G4p3EWirscJEQ/cHqnT/iuH6oNZOB94nBjWbMnhGEPxsZm1eyIW0C/9jLI0Fow4W5DXLjEI7mn1g==", - "dev": true, - "dependencies": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.2", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-airbnb-base": { - "version": "14.2.1", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz", - "integrity": "sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA==", - "dev": true, - "dependencies": { - "confusing-browser-globals": "^1.0.10", - "object.assign": "^4.1.2", - "object.entries": "^1.1.2" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "eslint": "^5.16.0 || ^6.8.0 || ^7.2.0", - "eslint-plugin-import": "^2.22.1" - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", - "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", - "dev": true, - "dependencies": { - "debug": "^2.6.9", - "resolve": "^1.13.1" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/eslint-module-utils": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz", - "integrity": "sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "pkg-dir": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.23.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.23.4.tgz", - "integrity": "sha512-6/wP8zZRsnQFiR3iaPFgh5ImVRM1WN5NUWfTIRqwOdeiGJlBcSk82o1FEVq8yXmy4lkIzTo7YhHCIxlU/2HyEQ==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.3", - "array.prototype.flat": "^1.2.4", - "debug": "^2.6.9", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.4", - "eslint-module-utils": "^2.6.1", - "find-up": "^2.0.0", - "has": "^1.0.3", - "is-core-module": "^2.4.0", - "minimatch": "^3.0.4", - "object.values": "^1.1.3", - "pkg-up": "^2.0.0", - "read-pkg-up": "^3.0.0", - "resolve": "^1.20.0", - "tsconfig-paths": "^3.9.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "dependencies": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "dependencies": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/execa/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/execa/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/execa/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/execa/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/execa/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/execa/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "node_modules/fast-url-parser": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", - "integrity": "sha1-9K8+qfNNiicc9YrSs3WfQx8LMY0=", - "dev": true, - "dependencies": { - "punycode": "^1.3.2" - } - }, - "node_modules/fast-url-parser/node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", - "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", - "dev": true - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/globals": { - "version": "13.9.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz", - "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", - "dev": true - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "node_modules/is-bigint": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", - "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", - "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", - "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", - "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", - "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", - "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-regex": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", - "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-string": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", - "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/js2xmlparser": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.1.tgz", - "integrity": "sha512-KrPTolcw6RocpYjdC7pL7v62e55q7qOMHvLX1UCLc5AAS8qeJ6nukarEJAF2KL2PZxlbGueEbINqZR2bDe/gUw==", - "dev": true, - "dependencies": { - "xmlcreate": "^2.0.3" - } - }, - "node_modules/jsdoc": { - "version": "3.6.7", - "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.7.tgz", - "integrity": "sha512-sxKt7h0vzCd+3Y81Ey2qinupL6DpRSZJclS04ugHDNmRUXGzqicMJ6iwayhSA0S0DwwX30c5ozyUthr1QKF6uw==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.9.4", - "bluebird": "^3.7.2", - "catharsis": "^0.9.0", - "escape-string-regexp": "^2.0.0", - "js2xmlparser": "^4.0.1", - "klaw": "^3.0.0", - "markdown-it": "^10.0.0", - "markdown-it-anchor": "^5.2.7", - "marked": "^2.0.3", - "mkdirp": "^1.0.4", - "requizzle": "^0.2.3", - "strip-json-comments": "^3.1.0", - "taffydb": "2.6.2", - "underscore": "~1.13.1" - }, - "bin": { - "jsdoc": "jsdoc.js" - }, - "engines": { - "node": ">=8.15.0" - } - }, - "node_modules/jsdoc/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/klaw": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", - "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.9" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/linkify-it": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", - "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", - "dev": true, - "dependencies": { - "uc.micro": "^1.0.1" - } - }, - "node_modules/load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", - "dev": true - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/markdown-it": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", - "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "entities": "~2.0.0", - "linkify-it": "^2.0.0", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" - }, - "bin": { - "markdown-it": "bin/markdown-it.js" - } - }, - "node_modules/markdown-it-anchor": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz", - "integrity": "sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA==", - "dev": true, - "peerDependencies": { - "markdown-it": "*" - } - }, - "node_modules/marked": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/marked/-/marked-2.0.7.tgz", - "integrity": "sha512-BJXxkuIfJchcXOJWTT2DOL+yFWifFv2yGYOUzvXg8Qz610QKw+sHCvTMYwA+qWGhlA2uivBezChZ/pBy1tWdkQ==", - "dev": true, - "bin": { - "marked": "bin/marked" - }, - "engines": { - "node": ">= 8.16.2" - } - }, - "node_modules/mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", - "dev": true - }, - "node_modules/mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", - "dev": true, - "dependencies": { - "mime-db": "1.51.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "node_modules/negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "dependencies": { - "path-key": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm-run-path/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/object-inspect": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", - "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.entries": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.4.tgz", - "integrity": "sha512-h4LWKWE+wKQGhtMjZEBud7uLGhqyLwj8fpHOarZhD2uY3C9cRtk57VQ89ke3moByLXMedqs3XCHzyb4AmA2DjA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.values": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", - "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/path-to-regexp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz", - "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==", - "dev": true - }, - "node_modules/path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "dependencies": { - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "dependencies": { - "find-up": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", - "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", - "dev": true, - "dependencies": { - "find-up": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "dev": true, - "dependencies": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", - "dev": true, - "dependencies": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/registry-auth-token": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", - "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", - "dev": true, - "dependencies": { - "rc": "^1.1.6", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/registry-url": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", - "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", - "dev": true, - "dependencies": { - "rc": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/requizzle": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz", - "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==", - "dev": true, - "dependencies": { - "lodash": "^4.17.14" - } - }, - "node_modules/resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "dev": true, - "dependencies": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/serve": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/serve/-/serve-13.0.2.tgz", - "integrity": "sha512-71R6fKvNgKrqARAag6lYJNnxDzpH7DCNrMuvPY5PLVaC2PDhJsGTj/34o4o4tPWhTuLgEXqvgnAWbATQ9zGZTQ==", - "dev": true, - "dependencies": { - "@zeit/schemas": "2.6.0", - "ajv": "6.12.6", - "arg": "2.0.0", - "boxen": "5.1.2", - "chalk": "2.4.1", - "clipboardy": "2.3.0", - "compression": "1.7.3", - "serve-handler": "6.1.3", - "update-check": "1.5.2" - }, - "bin": { - "serve": "bin/serve.js" - } - }, - "node_modules/serve-handler": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.3.tgz", - "integrity": "sha512-FosMqFBNrLyeiIDvP1zgO6YoTzFYHxLDEIavhlmQ+knB2Z7l1t+kGLHkZIDN7UVWqQAmKI3D20A6F6jo3nDd4w==", - "dev": true, - "dependencies": { - "bytes": "3.0.0", - "content-disposition": "0.5.2", - "fast-url-parser": "1.1.3", - "mime-types": "2.1.18", - "minimatch": "3.0.4", - "path-is-inside": "1.0.2", - "path-to-regexp": "2.2.1", - "range-parser": "1.2.0" - } - }, - "node_modules/serve-handler/node_modules/mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-handler/node_modules/mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "dev": true, - "dependencies": { - "mime-db": "~1.33.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve/node_modules/chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/serve/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/signal-exit": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", - "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", - "dev": true - }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/slice-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/slice-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz", - "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==", - "dev": true - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "node_modules/string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/table": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", - "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", - "dev": true, - "dependencies": { - "ajv": "^8.0.1", - "lodash.clonedeep": "^4.5.0", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/table/node_modules/ajv": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.0.tgz", - "integrity": "sha512-cnUG4NSBiM4YFBxgZIj/In3/6KX+rQ2l2YPRVcvAMQGWEPKuXoPIhxzwqh31jA3IPbI4qEOp/5ILI4ynioXsGQ==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/taffydb": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz", - "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=", - "dev": true - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "node_modules/tsconfig-paths": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", - "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", - "dev": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.0", - "strip-bom": "^3.0.0" - } - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", - "dev": true - }, - "node_modules/unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/underscore": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz", - "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==", - "dev": true - }, - "node_modules/update-check": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/update-check/-/update-check-1.5.2.tgz", - "integrity": "sha512-1TrmYLuLj/5ZovwUS7fFd1jMH3NnFDN1y1A8dboedIDt7zs/zJMo6TwwlhYKkSeEwzleeiSBV5/3c9ufAQWDaQ==", - "dev": true, - "dependencies": { - "registry-auth-token": "3.3.2", - "registry-url": "3.1.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "dev": true, - "dependencies": { - "string-width": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/wrap-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "node_modules/xmlcreate": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.3.tgz", - "integrity": "sha512-HgS+X6zAztGa9zIK3Y3LXuJes33Lz9x+YyTxgrkIdabu2vqcGOWwdfCpf1hWLRrd553wd4QCDf6BBO6FfdsRiQ==", - "dev": true - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", - "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", - "dev": true - }, - "@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.14.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - } - } - }, - "@babel/parser": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.5.tgz", - "integrity": "sha512-TM8C+xtH/9n1qzX+JNHi7AN2zHMTiPUtspO0ZdHflW8KaskkALhMmuMHb4bCmNdv9VAPzJX3/bXqkVLnAvsPfg==", - "dev": true - }, - "@eslint/eslintrc": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", - "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - } - }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", - "dev": true - }, - "@zeit/schemas": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.6.0.tgz", - "integrity": "sha512-uUrgZ8AxS+Lio0fZKAipJjAh415JyrOZowliZAzmnJSsf7piVL5w+G0+gFJ0KSu3QRhvui/7zuvpLz03YjXAhg==", - "dev": true - }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "dev": true, - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", - "dev": true, - "requires": {} - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "dev": true, - "requires": { - "string-width": "^4.1.0" - } - }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "arch": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", - "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", - "dev": true - }, - "arg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arg/-/arg-2.0.0.tgz", - "integrity": "sha512-XxNTUzKnz1ctK3ZIcI2XUPlD96wbHP2nGqkPKpvk/HNRlPveYrXIVSTk9m3LcqOgDPg3B1nMvdV/K8wZd7PG4w==", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "array-includes": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", - "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.5" - } - }, - "array.prototype.flat": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", - "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" - } - }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "boxen": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", - "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", - "dev": true, - "requires": { - "ansi-align": "^3.0.0", - "camelcase": "^6.2.0", - "chalk": "^4.1.0", - "cli-boxes": "^2.2.1", - "string-width": "^4.2.2", - "type-fest": "^0.20.2", - "widest-line": "^3.1.0", - "wrap-ansi": "^7.0.0" - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "dev": true - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - }, - "catharsis": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", - "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", - "dev": true, - "requires": { - "lodash": "^4.17.15" - } - }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "cli-boxes": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", - "dev": true - }, - "clipboardy": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-2.3.0.tgz", - "integrity": "sha512-mKhiIL2DrQIsuXMgBgnfEHOZOryC7kY7YO//TN6c63wlEm3NG5tz+YgY5rVi29KCmq/QQjKYvM7a19+MDOTHOQ==", - "dev": true, - "requires": { - "arch": "^2.1.1", - "execa": "^1.0.0", - "is-wsl": "^2.1.1" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dev": true, - "requires": { - "mime-db": ">= 1.43.0 < 2" - } - }, - "compression": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.3.tgz", - "integrity": "sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==", - "dev": true, - "requires": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.14", - "debug": "2.6.9", - "on-headers": "~1.0.1", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "confusing-browser-globals": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.10.tgz", - "integrity": "sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA==", - "dev": true - }, - "content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=", - "dev": true - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - } - }, - "entities": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", - "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", - "dev": true - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.18.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", - "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "is-callable": "^1.2.3", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.3", - "is-string": "^1.0.6", - "object-inspect": "^1.10.3", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "eslint": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.28.0.tgz", - "integrity": "sha512-UMfH0VSjP0G4p3EWirscJEQ/cHqnT/iuH6oNZOB94nBjWbMnhGEPxsZm1eyIW0C/9jLI0Fow4W5DXLjEI7mn1g==", - "dev": true, - "requires": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.2", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - } - }, - "eslint-config-airbnb-base": { - "version": "14.2.1", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz", - "integrity": "sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA==", - "dev": true, - "requires": { - "confusing-browser-globals": "^1.0.10", - "object.assign": "^4.1.2", - "object.entries": "^1.1.2" - } - }, - "eslint-import-resolver-node": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", - "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", - "dev": true, - "requires": { - "debug": "^2.6.9", - "resolve": "^1.13.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "eslint-module-utils": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz", - "integrity": "sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A==", - "dev": true, - "requires": { - "debug": "^3.2.7", - "pkg-dir": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-plugin-import": { - "version": "2.23.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.23.4.tgz", - "integrity": "sha512-6/wP8zZRsnQFiR3iaPFgh5ImVRM1WN5NUWfTIRqwOdeiGJlBcSk82o1FEVq8yXmy4lkIzTo7YhHCIxlU/2HyEQ==", - "dev": true, - "requires": { - "array-includes": "^3.1.3", - "array.prototype.flat": "^1.2.4", - "debug": "^2.6.9", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.4", - "eslint-module-utils": "^2.6.1", - "find-up": "^2.0.0", - "has": "^1.0.3", - "is-core-module": "^2.4.0", - "minimatch": "^3.0.4", - "object.values": "^1.1.3", - "pkg-up": "^2.0.0", - "read-pkg-up": "^3.0.0", - "resolve": "^1.20.0", - "tsconfig-paths": "^3.9.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - }, - "espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "fast-url-parser": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", - "integrity": "sha1-9K8+qfNNiicc9YrSs3WfQx8LMY0=", - "dev": true, - "requires": { - "punycode": "^1.3.2" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - } - } - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", - "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "globals": { - "version": "13.9.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz", - "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", - "dev": true - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true - }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-bigint": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", - "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==", - "dev": true - }, - "is-boolean-object": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", - "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-callable": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", - "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", - "dev": true - }, - "is-core-module": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", - "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-date-object": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", - "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==", - "dev": true - }, - "is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", - "dev": true - }, - "is-number-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", - "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==", - "dev": true - }, - "is-regex": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", - "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-symbols": "^1.0.2" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "is-string": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", - "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", - "dev": true - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "requires": { - "is-docker": "^2.0.0" - } - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "js2xmlparser": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.1.tgz", - "integrity": "sha512-KrPTolcw6RocpYjdC7pL7v62e55q7qOMHvLX1UCLc5AAS8qeJ6nukarEJAF2KL2PZxlbGueEbINqZR2bDe/gUw==", - "dev": true, - "requires": { - "xmlcreate": "^2.0.3" - } - }, - "jsdoc": { - "version": "3.6.7", - "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.7.tgz", - "integrity": "sha512-sxKt7h0vzCd+3Y81Ey2qinupL6DpRSZJclS04ugHDNmRUXGzqicMJ6iwayhSA0S0DwwX30c5ozyUthr1QKF6uw==", - "dev": true, - "requires": { - "@babel/parser": "^7.9.4", - "bluebird": "^3.7.2", - "catharsis": "^0.9.0", - "escape-string-regexp": "^2.0.0", - "js2xmlparser": "^4.0.1", - "klaw": "^3.0.0", - "markdown-it": "^10.0.0", - "markdown-it-anchor": "^5.2.7", - "marked": "^2.0.3", - "mkdirp": "^1.0.4", - "requizzle": "^0.2.3", - "strip-json-comments": "^3.1.0", - "taffydb": "2.6.2", - "underscore": "~1.13.1" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - } - } - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "klaw": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", - "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.9" - } - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "linkify-it": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", - "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", - "dev": true, - "requires": { - "uc.micro": "^1.0.1" - } - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", - "dev": true - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "markdown-it": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", - "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "entities": "~2.0.0", - "linkify-it": "^2.0.0", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" - } - }, - "markdown-it-anchor": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz", - "integrity": "sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA==", - "dev": true, - "requires": {} - }, - "marked": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/marked/-/marked-2.0.7.tgz", - "integrity": "sha512-BJXxkuIfJchcXOJWTT2DOL+yFWifFv2yGYOUzvXg8Qz610QKw+sHCvTMYwA+qWGhlA2uivBezChZ/pBy1tWdkQ==", - "dev": true - }, - "mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", - "dev": true - }, - "mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", - "dev": true - }, - "mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", - "dev": true, - "requires": { - "mime-db": "1.51.0" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "requires": { - "path-key": "^2.0.0" - }, - "dependencies": { - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - } - } - }, - "object-inspect": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", - "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "object.entries": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.4.tgz", - "integrity": "sha512-h4LWKWE+wKQGhtMjZEBud7uLGhqyLwj8fpHOarZhD2uY3C9cRtk57VQ89ke3moByLXMedqs3XCHzyb4AmA2DjA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.2" - } - }, - "object.values": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", - "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.2" - } - }, - "on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "path-to-regexp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz", - "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==", - "dev": true - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } - }, - "pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", - "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", - "dev": true - }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - } - } - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } - }, - "read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" - } - }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, - "registry-auth-token": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", - "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", - "dev": true, - "requires": { - "rc": "^1.1.6", - "safe-buffer": "^5.0.1" - } - }, - "registry-url": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", - "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", - "dev": true, - "requires": { - "rc": "^1.0.1" - } - }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true - }, - "requizzle": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz", - "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "dev": true, - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "serve": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/serve/-/serve-13.0.2.tgz", - "integrity": "sha512-71R6fKvNgKrqARAag6lYJNnxDzpH7DCNrMuvPY5PLVaC2PDhJsGTj/34o4o4tPWhTuLgEXqvgnAWbATQ9zGZTQ==", - "dev": true, - "requires": { - "@zeit/schemas": "2.6.0", - "ajv": "6.12.6", - "arg": "2.0.0", - "boxen": "5.1.2", - "chalk": "2.4.1", - "clipboardy": "2.3.0", - "compression": "1.7.3", - "serve-handler": "6.1.3", - "update-check": "1.5.2" - }, - "dependencies": { - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - } - } - }, - "serve-handler": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.3.tgz", - "integrity": "sha512-FosMqFBNrLyeiIDvP1zgO6YoTzFYHxLDEIavhlmQ+knB2Z7l1t+kGLHkZIDN7UVWqQAmKI3D20A6F6jo3nDd4w==", - "dev": true, - "requires": { - "bytes": "3.0.0", - "content-disposition": "0.5.2", - "fast-url-parser": "1.1.3", - "mime-types": "2.1.18", - "minimatch": "3.0.4", - "path-is-inside": "1.0.2", - "path-to-regexp": "2.2.1", - "range-parser": "1.2.0" - }, - "dependencies": { - "mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "dev": true - }, - "mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "dev": true, - "requires": { - "mime-db": "~1.33.0" - } - } - } - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "signal-exit": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", - "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", - "dev": true - }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - } - } - }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz", - "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==", - "dev": true - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "table": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", - "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", - "dev": true, - "requires": { - "ajv": "^8.0.1", - "lodash.clonedeep": "^4.5.0", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ajv": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.0.tgz", - "integrity": "sha512-cnUG4NSBiM4YFBxgZIj/In3/6KX+rQ2l2YPRVcvAMQGWEPKuXoPIhxzwqh31jA3IPbI4qEOp/5ILI4ynioXsGQ==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - } - } - }, - "taffydb": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz", - "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=", - "dev": true - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "tsconfig-paths": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", - "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", - "dev": true, - "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.0", - "strip-bom": "^3.0.0" - } - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", - "dev": true - }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - } - }, - "underscore": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz", - "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==", - "dev": true - }, - "update-check": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/update-check/-/update-check-1.5.2.tgz", - "integrity": "sha512-1TrmYLuLj/5ZovwUS7fFd1jMH3NnFDN1y1A8dboedIDt7zs/zJMo6TwwlhYKkSeEwzleeiSBV5/3c9ufAQWDaQ==", - "dev": true, - "requires": { - "registry-auth-token": "3.3.2", - "registry-url": "3.1.0" - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "dev": true, - "requires": { - "string-width": "^4.0.0" - } - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xmlcreate": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.3.tgz", - "integrity": "sha512-HgS+X6zAztGa9zIK3Y3LXuJes33Lz9x+YyTxgrkIdabu2vqcGOWwdfCpf1hWLRrd553wd4QCDf6BBO6FfdsRiQ==", - "dev": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } -} diff --git a/platform/javascript/package.json b/platform/javascript/package.json deleted file mode 100644 index 2ff1544837..0000000000 --- a/platform/javascript/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "godot", - "private": true, - "version": "1.0.0", - "description": "Development and linting setup for Godot's HTML5 platform code", - "scripts": { - "docs": "jsdoc --template js/jsdoc2rst/ js/engine/engine.js js/engine/config.js --destination ''", - "lint": "npm run lint:engine && npm run lint:libs && npm run lint:modules && npm run lint:tools", - "lint:engine": "eslint \"js/engine/*.js\" --no-eslintrc -c .eslintrc.engine.js", - "lint:libs": "eslint \"js/libs/*.js\" --no-eslintrc -c .eslintrc.libs.js", - "lint:modules": "eslint \"../../modules/**/*.js\" --no-eslintrc -c .eslintrc.libs.js", - "lint:tools": "eslint \"js/jsdoc2rst/**/*.js\" --no-eslintrc -c .eslintrc.engine.js", - "format": "npm run format:engine && npm run format:libs && npm run format:modules && npm run format:tools", - "format:engine": "npm run lint:engine -- --fix", - "format:libs": "npm run lint:libs -- --fix", - "format:modules": "npm run lint:modules -- --fix", - "format:tools": "npm run lint:tools -- --fix", - "serve": "serve" - }, - "author": "Godot Engine contributors", - "license": "MIT", - "devDependencies": { - "eslint": "^7.28.0", - "eslint-config-airbnb-base": "^14.2.1", - "eslint-plugin-import": "^2.23.4", - "jsdoc": "^3.6.7", - "serve": "^13.0.2" - } -} diff --git a/platform/javascript/platform_config.h b/platform/javascript/platform_config.h deleted file mode 100644 index 1970fe0fa0..0000000000 --- a/platform/javascript/platform_config.h +++ /dev/null @@ -1,33 +0,0 @@ -/*************************************************************************/ -/* platform_config.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include <alloca.h> - -#define OPENGL_INCLUDE_H "platform/javascript/godot_webgl2.h" diff --git a/platform/javascript/run_icon.png b/platform/javascript/run_icon.png Binary files differdeleted file mode 100644 index 574abb0150..0000000000 --- a/platform/javascript/run_icon.png +++ /dev/null diff --git a/platform/javascript/serve.json b/platform/javascript/serve.json deleted file mode 100644 index f2ef24751f..0000000000 --- a/platform/javascript/serve.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "public": "../../bin", - "headers": [{ - "source": "**/*", - "headers": [ - { - "key": "Cross-Origin-Embedder-Policy", - "value": "require-corp" - }, { - "key": "Cross-Origin-Opener-Policy", - "value": "same-origin" - }, { - "key": "Access-Control-Allow-Origin", - "value": "*" - }, { - "key": "Cache-Control", - "value": "no-store, max-age=0" - } - ] - }] -} |