diff --git a/.gitignore b/.gitignore index 46e1be12b5..730e80592f 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ *.dir *.idea/ .build-vs/ +.cache/ .cproject .project .vs/ @@ -13,6 +14,7 @@ CMakeFiles CMakeLists.txt.user cmake-build-* cmake_install.cmake +compile_commands.json install_manifest.txt Makefile @@ -33,11 +35,15 @@ Thumbs.db /user/ /sync/ /temp/ +GPUCache/ + # Customization is not supposed to be committed customization.lua + # The COMMIT info is generated everytime CMake is run COMMIT.md *_codegen.cpp + # SkyBrowser Module downloaded data /modules/skybrowser/wwtimagedata doc diff --git a/.gitmodules b/.gitmodules index 8bffd188f8..68bba6a41a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -41,7 +41,12 @@ [submodule "support/doxygen/css"] path = support/doxygen/css url = https://github.com/jothepro/doxygen-awesome-css.git - [submodule "modules/audio/ext/soloud"] path = modules/audio/ext/soloud url = https://github.com/jarikomppa/soloud +[submodule "modules/opensoundcontrol/ext/oscpack"] + path = modules/opensoundcontrol/ext/oscpack + url = https://github.com/OpenSpace/oscpack.git +[submodule "ext/json"] + path = ext/json + url = https://github.com/nlohmann/json diff --git a/.mailmap b/.mailmap index d7ab0d7d56..c93293b1b3 100644 --- a/.mailmap +++ b/.mailmap @@ -15,11 +15,14 @@ Andreas Engberg <48772850+engbergandreas@users.noreply. Anders Lundkvist Lundkvist Anders Lundkvist lundkvistarn +Anders Lundkvist <57524362+lundkvistarn@users.noreply.github.com> Anton Arbring antar420 Axel Kollberg Kollberg +Benjamin Mastripolito benpm + Caroline Gard carolinegard Caroline Gard CarolineGard diff --git a/CMakeLists.txt b/CMakeLists.txt index 2d4304ad6d..f6079ff825 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,11 +27,16 @@ cmake_policy(VERSION 3.25) project(OpenSpace) +# CMake 4.0 will no longer allow minimum required version below 3.5 and some of our +# dependencies have not been updated to reflect this. To make things work, we blanked +# require to 3.10 here to remove those issues. Once CMake configures and generates +# successfully without this next line, it can be removed +set(CMAKE_POLICY_VERSION_MINIMUM 3.10) + set(OPENSPACE_RELEASE_BUILD OFF) set(OPENSPACE_VERSION_MAJOR) set(OPENSPACE_VERSION_MINOR) set(OPENSPACE_VERSION_PATCH) -set(OPENSPACE_VERSION_STRING) include(${PROJECT_SOURCE_DIR}/support/cmake/module_common.cmake) include(${PROJECT_SOURCE_DIR}/ext/ghoul/support/cmake/message_macros.cmake) @@ -66,7 +71,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin) if (MSVC) # Force all builds to be multi-threaded and increase number of sections in obj files - add_definitions(/MP /bigobj) + add_compile_options(/MP /bigobj) endif () ########################################################################################## @@ -151,15 +156,15 @@ add_custom_target( ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/__codegen.h" ) -add_dependencies(run_codegen codegen) +add_dependencies(run_codegen codegen-tool) add_custom_command( OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/__codegen.h" - COMMAND codegen ARGS "modules" "src" + COMMAND codegen-tool ARGS "modules" "src" WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" VERBATIM ) set_target_properties(codegen-lib PROPERTIES FOLDER "support") -set_target_properties(codegen PROPERTIES FOLDER "support") +set_target_properties(codegen-tool PROPERTIES FOLDER "support") set_target_properties(run_codegen PROPERTIES FOLDER "support") diff --git a/apps/DocsWriter/main.cpp b/apps/DocsWriter/main.cpp index 1bfe2e79b2..219b784819 100644 --- a/apps/DocsWriter/main.cpp +++ b/apps/DocsWriter/main.cpp @@ -31,7 +31,7 @@ #include #include -int main(int argc, char** argv) { +int main(int, char** argv) { using namespace openspace; ghoul::logging::LogManager::initialize( diff --git a/apps/OpenSpace-MinVR/CMakeLists.txt b/apps/OpenSpace-MinVR/CMakeLists.txt index 4f9e59fd48..f924e8d1ea 100644 --- a/apps/OpenSpace-MinVR/CMakeLists.txt +++ b/apps/OpenSpace-MinVR/CMakeLists.txt @@ -2,7 +2,7 @@ # # # OpenSpace # # # -# Copyright (c) 2014-2022 # +# Copyright (c) 2014-2025 # # # # 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 # @@ -22,7 +22,6 @@ # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # ########################################################################################## -include(${PROJECT_SOURCE_DIR}/ext/ghoul/support/cmake/copy_shared_libraries.cmake) include(${PROJECT_SOURCE_DIR}/support/cmake/application_definition.cmake) include(${PROJECT_SOURCE_DIR}/support/cmake/global_variables.cmake) @@ -50,7 +49,7 @@ target_include_directories(OpenSpace-MinVR PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/ex target_include_directories(OpenSpace-MinVR PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/ext/minvr/external/GLFW/src/include) -target_link_libraries(OpenSpace-MinVR PUBLIC openspace-core MinVR) +target_link_libraries(OpenSpace-MinVR PUBLIC openspace-core openspace-module-collection MinVR) # Web Browser and Web gui # Why not put these in the module's path? Because they do not have access to the diff --git a/apps/OpenSpace-MinVR/main.cpp b/apps/OpenSpace-MinVR/main.cpp index 961bb15b9c..42742a05c1 100644 --- a/apps/OpenSpace-MinVR/main.cpp +++ b/apps/OpenSpace-MinVR/main.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -36,8 +37,8 @@ #include #include #include +#include #include -#include #include // @TODO: Add Spout support @@ -115,7 +116,7 @@ void Handler::onVREvent(const VRDataIndex& eventData) { const VRAnalogEvent& event = static_cast(eventData); } else if (isButtonEvent) { - if (!global::windowDelegate.isMaster()) { + if (!global::windowDelegate->isMaster()) { return; } const VRButtonEvent& event = static_cast(eventData); @@ -130,7 +131,7 @@ void Handler::onVREvent(const VRDataIndex& eventData) { std::string keyName = buttonName.substr(beg, sep - beg); std::string actionName = buttonName.substr(sep + 1); - Key key = KeyMapping.find(keyName)->second; + Key key = stringToKey(keyName).key; KeyAction action; if (actionName == "Up") { @@ -157,12 +158,12 @@ void Handler::onVREvent(const VRDataIndex& eventData) { } using KM = KeyModifier; - KM mod = KM::NoModifier; - mod |= keyboardState.modifierShift ? KM::Shift : KM::NoModifier; - mod |= keyboardState.modifierCtrl ? KM::Control : KM::NoModifier; - mod |= keyboardState.modifierAlt ? KM::Alt : KM::NoModifier; + KM mod = KM::None; + mod |= keyboardState.modifierShift ? KM::Shift : KM::None; + mod |= keyboardState.modifierCtrl ? KM::Control : KM::None; + mod |= keyboardState.modifierAlt ? KM::Alt : KM::None; - openspace::global::openSpaceEngine.keyboardCallback(key, mod, action); + global::openSpaceEngine->keyboardCallback(key, mod, action, IsGuiWindow::Yes); } if (buttonName.size() >= 8 && buttonName.substr(0, 8) == "MouseBtn") { @@ -203,24 +204,29 @@ void Handler::onVREvent(const VRDataIndex& eventData) { } using KM = KeyModifier; - KM mod = KM::NoModifier; - mod |= keyboardState.modifierShift ? KM::Shift : KM::NoModifier; - mod |= keyboardState.modifierCtrl ? KM::Control : KM::NoModifier; - mod |= keyboardState.modifierAlt ? KM::Alt : KM::NoModifier; + KM mod = KM::None; + mod |= keyboardState.modifierShift ? KM::Shift : KM::None; + mod |= keyboardState.modifierCtrl ? KM::Control : KM::None; + mod |= keyboardState.modifierAlt ? KM::Alt : KM::None; - global::openSpaceEngine.mouseButtonCallback(button, action, mod); + global::openSpaceEngine->mouseButtonCallback( + button, + action, + mod, + IsGuiWindow::Yes + ); } } else if (type == "CursorMove") { - if (!global::windowDelegate.isMaster()) { + if (!global::windowDelegate->isMaster()) { return; } const VRCursorEvent& event = static_cast(eventData); const float* pos = event.getPos(); windowingGlobals.mousePosition = glm::vec2(pos[0], pos[1]); - openspace::global::openSpaceEngine.mousePositionCallback(pos[0], pos[1]); + global::openSpaceEngine->mousePositionCallback(pos[0], pos[1], IsGuiWindow::Yes); // @TODO(abock): Support mouse wheel //openspace::global::openSpaceEngine.mouseScrollWheelCallback(posX, posY); @@ -229,19 +235,19 @@ void Handler::onVREvent(const VRDataIndex& eventData) { const VRTrackerEvent& event = static_cast(eventData); } else if (type == "OpenSpaceMessage") { - if (global::windowDelegate.isMaster()) { + if (global::windowDelegate->isMaster()) { // We don't want the message if we are the master as we already have the state return; } const int frameNumber = eventData.getValue("FrameNumber"); const int nBytes = eventData.getValue("NBytes"); std::vector intData = eventData.getValue("SynchronizationData"); - char* data = reinterpret_cast(intData.data()); + std::byte* data = reinterpret_cast(intData.data()); - std::vector synchronizationBuffer(nBytes); + std::vector synchronizationBuffer(nBytes); std::copy(data, data + nBytes, synchronizationBuffer.begin()); - global::openSpaceEngine.decode(std::move(synchronizationBuffer)); + global::openSpaceEngine->decode(std::move(synchronizationBuffer)); } else { LERRORC("onVREvent()", std::format("Received an event of unknown type {}", type)); @@ -263,7 +269,7 @@ void Handler::onVRRenderContext(const VRDataIndex& stateData) { windowingGlobals.framebufferSize.x = stateData.getValue("FramebufferWidth"); windowingGlobals.framebufferSize.y = stateData.getValue("FramebufferHeight"); - global::openSpaceEngine.initializeGL(); + global::openSpaceEngine->initializeGL(); HasInitializedGL = true; } @@ -279,14 +285,14 @@ void Handler::onVRRenderScene(const VRDataIndex& stateData) { glm::mat4 projectionMatrix = glm::make_mat4(state.getProjectionMatrix()); glm::mat4 viewMatrix = glm::make_mat4(state.getViewMatrix()); try { - openspace::global::openSpaceEngine.render( + openspace::global::openSpaceEngine->render( // @TODO(abock) we should probably use the user position here? glm::mat4(1.f), viewMatrix, projectionMatrix ); - openspace::global::openSpaceEngine.drawOverlays(); - openspace::global::openSpaceEngine.postDraw(); + openspace::global::openSpaceEngine->drawOverlays(); + openspace::global::openSpaceEngine->postDraw(); } catch (const ghoul::RuntimeError& e) { LERRORC(e.component, e.message); @@ -301,29 +307,22 @@ void Handler::appendNewInputEventsSinceLastCall(VRDataQueue* queue) { void setupMinVrDelegateFunctions(VRMain& main) { // Sets up the OpenSpace WindowDelegate callback functions - WindowDelegate& delegate = global::windowDelegate; + WindowDelegate* delegate = global::windowDelegate; - delegate.nWindows = []() { return windowingGlobals.nWindows; }; - delegate.currentWindowSize = []() { return windowingGlobals.windowSize; }; - delegate.currentWindowResolution = delegate.currentWindowSize; - delegate.currentDrawBufferResolution = delegate.currentWindowResolution; - delegate.currentViewportSize = delegate.currentWindowResolution; + delegate->nWindows = []() { return windowingGlobals.nWindows; }; + delegate->currentWindowSize = []() { return windowingGlobals.windowSize; }; + delegate->currentDrawBufferResolution = delegate->currentWindowSize; + delegate->currentViewportSize = delegate->currentWindowSize; - delegate.averageDeltaTime = []() -> double { + delegate->averageDeltaTime = []() -> double { return windowingGlobals.averageDeltatime; }; - delegate.deltaTime = []() -> double { return windowingGlobals.deltaTime; }; + delegate->deltaTime = []() -> double { return windowingGlobals.deltaTime; }; - delegate.mousePosition = []() { - return windowingGlobals.mousePosition; - }; - delegate.mouseButtons = [](int) { - return windowingGlobals.mouseButtons; - }; - delegate.isMaster = []() { return IsMasterNode; }; + delegate->isMaster = []() { return IsMasterNode; }; - delegate.openGLProcedureAddress = [](const char* func) { + delegate->openGLProcedureAddress = [](const char* func) { VRWindowToolkit* wtk = engine.getWindowToolkit("VRGLFWWindowToolkit"); VRglproc procAddress = wtk->getProcAddress(func); return procAddress; @@ -348,12 +347,13 @@ int main(int argc, char** argv) { } ghoul::initialize(); + global::create(); // Register the path of the executable, // to make it possible to find other files in the same directory. FileSys.registerPathToken( "${BIN}", - ghoul::filesystem::File(absPath(argv[0])).directoryName(), + absPath(argv[0]).parent_path(), ghoul::filesystem::FileSystem::Override::Yes ); @@ -362,22 +362,42 @@ int main(int argc, char** argv) { try { // Find configuration //std::string configurationFilePath = commandlineArguments.configurationName; - //if (commandlineArguments.configurationName.empty()) { LDEBUG("Finding configuration"); - std::string configurationFilePath = configuration::findConfiguration(); - //} + std::filesystem::path configurationFilePath = findConfiguration(); configurationFilePath = absPath(configurationFilePath); - if (!FileSys.fileExists(configurationFilePath)) { - LFATALC("main", "Could not find configuration: " + configurationFilePath); + if (!std::filesystem::exists(configurationFilePath)) { + LFATALC( + "main", + std::format("Could not find configuration: {}", configurationFilePath) + ); exit(EXIT_FAILURE); } LINFO(std::format("Configuration Path: '{}'", configurationFilePath)); + // Register the base path as the directory where the configuration file lives + std::filesystem::path base = configurationFilePath.parent_path(); + FileSys.registerPathToken("${BASE}", std::move(base)); + +#ifdef WIN32 + glm::ivec2 size = glm::ivec2(1920, 1080); + DEVMODEW dm = { 0 }; + dm.dmSize = sizeof(DEVMODEW); + BOOL success = EnumDisplaySettingsW(nullptr, ENUM_CURRENT_SETTINGS, &dm); + if (success) { + size.x = dm.dmPelsWidth; + size.y = dm.dmPelsHeight; + } +#else // ^^^^ WIN32 // !WIN32 vvvv + const glm::ivec2 size = glm::ivec2(1920, 1080); +#endif // WIN32 + // Loading configuration from disk LDEBUG("Loading configuration from disk"); - global::configuration = configuration::loadConfigurationFromFile( - configurationFilePath + *global::configuration = loadConfigurationFromFile( + configurationFilePath, + findSettings(), + size ); // If the user requested a commandline-based configuation script that should @@ -393,9 +413,9 @@ int main(int argc, char** argv) { //} // Determining MinVR configuration file - LDEBUG("MinVR Configuration file: " + global::configuration.windowConfiguration); + LDEBUG("MinVR Configuration file: " + global::configuration->windowConfiguration); - windowConfiguration = global::configuration.windowConfiguration; + windowConfiguration = global::configuration->windowConfiguration; } catch (const documentation::SpecificationError& e) { LFATALC("main", "Loading of configuration file failed"); @@ -416,12 +436,12 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } - global::openSpaceEngine.registerPathTokens(); - global::openSpaceEngine.initialize(); + global::openSpaceEngine->registerPathTokens(); + global::openSpaceEngine->initialize(); engine.addEventHandler(&handler); engine.addRenderHandler(&handler); - engine.loadConfig(global::configuration.windowConfiguration); + engine.loadConfig(global::configuration->windowConfiguration); // Yes, this still contains the OpenSpace-specific commandline arguments, but no one // will ever know if we use the remaining arguments or not; both commandline parsers // just ignore the arguments they don't understand @@ -432,7 +452,7 @@ int main(int argc, char** argv) { const std::string& name = engine.getName(); IsMasterNode = (name == MasterNode); - if (global::windowDelegate.isMaster()) { + if (global::windowDelegate->isMaster()) { engine.addInputDevice(&handler); } @@ -460,10 +480,10 @@ int main(int argc, char** argv) { - global::openSpaceEngine.preSynchronization(); + global::openSpaceEngine->preSynchronization(); - if (global::windowDelegate.isMaster()) { - std::vector syncBuffer = global::openSpaceEngine.encode(); + if (global::windowDelegate->isMaster()) { + std::vector syncBuffer = global::openSpaceEngine->encode(); VRDataIndex e("OpenSpace_Sync"); e.addData("EventType", "OpenSpaceMessage"); @@ -489,7 +509,7 @@ int main(int argc, char** argv) { engine.updateAllModels(); // @TODO(abock): Not sure if this should be before updateAllModels or here - global::openSpaceEngine.postSynchronizationPreDraw(); + global::openSpaceEngine->postSynchronizationPreDraw(); ++FrameNumber; } @@ -497,12 +517,12 @@ int main(int argc, char** argv) { engine.renderOnAllDisplays(); } while (!engine.getShutdown()); - global::openSpaceEngine.deinitializeGL(); + global::openSpaceEngine->deinitializeGL(); // This assumes that `shutdown` destroys the OpenGL state and thus have to happen // after the deinitializeGL function engine.shutdown(); - global::openSpaceEngine.deinitialize(); + global::openSpaceEngine->deinitialize(); exit(EXIT_SUCCESS); } diff --git a/apps/OpenSpace/CMakeLists.txt b/apps/OpenSpace/CMakeLists.txt index 240d706377..9fd276ac9c 100644 --- a/apps/OpenSpace/CMakeLists.txt +++ b/apps/OpenSpace/CMakeLists.txt @@ -77,7 +77,7 @@ endif () ##### if (APPLE) set(MACOSX_BUNDLE_ICON_FILE openspace.icns) - set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version" FORCE) + set(CMAKE_OSX_DEPLOYMENT_TARGET "13.3" CACHE STRING "Minimum OS X deployment version" FORCE) set(CMAKE_XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS "--deep" CACHE STRING "Other Code Signing Flags" FORCE) endif () @@ -113,6 +113,7 @@ begin_header("Dependency: SGCT") set(SGCT_TEXT OFF CACHE BOOL "" FORCE) set(SGCT_DEP_INCLUDE_FREETYPE OFF CACHE BOOL "" FORCE) set(SGCT_DEP_INCLUDE_FMT OFF CACHE BOOL "" FORCE) +set(SGCT_DEP_INCLUDE_JSON OFF CACHE BOOL "" FORCE) set(SGCT_DEP_INCLUDE_SCN OFF CACHE BOOL "" FORCE) set(SGCT_DEP_INCLUDE_CATCH2 OFF CACHE BOOL "" FORCE) diff --git a/apps/OpenSpace/ext/launcher/CMakeLists.txt b/apps/OpenSpace/ext/launcher/CMakeLists.txt index e3811a7521..796fb3505c 100644 --- a/apps/OpenSpace/ext/launcher/CMakeLists.txt +++ b/apps/OpenSpace/ext/launcher/CMakeLists.txt @@ -28,8 +28,10 @@ set(HEADER_FILES include/backgroundimage.h include/filesystemaccess.h include/launcherwindow.h + include/notificationwindow.h include/settingsdialog.h include/splitcombobox.h + include/usericon.h include/windowcolors.h include/profile/actiondialog.h include/profile/additionalscriptsdialog.h @@ -48,6 +50,7 @@ set(HEADER_FILES include/profile/timedialog.h include/profile/profileedit.h include/profile/propertiesdialog.h + include/profile/uipanelsdialog.h include/sgctedit/displaywindowunion.h include/sgctedit/monitorbox.h include/sgctedit/sgctedit.h @@ -58,8 +61,10 @@ set(SOURCE_FILES src/backgroundimage.cpp src/launcherwindow.cpp src/filesystemaccess.cpp + src/notificationwindow.cpp src/settingsdialog.cpp src/splitcombobox.cpp + src/usericon.cpp src/windowcolors.cpp src/profile/actiondialog.cpp src/profile/additionalscriptsdialog.cpp @@ -78,6 +83,7 @@ set(SOURCE_FILES src/profile/timedialog.cpp src/profile/profileedit.cpp src/profile/propertiesdialog.cpp + src/profile/uipanelsdialog.cpp src/sgctedit/sgctedit.cpp src/sgctedit/displaywindowunion.cpp src/sgctedit/monitorbox.cpp diff --git a/apps/OpenSpace/ext/launcher/include/launcherwindow.h b/apps/OpenSpace/ext/launcher/include/launcherwindow.h index cbe15c696f..c8b63783de 100644 --- a/apps/OpenSpace/ext/launcher/include/launcherwindow.h +++ b/apps/OpenSpace/ext/launcher/include/launcherwindow.h @@ -62,18 +62,16 @@ public: bool wasLaunchSelected() const; /** - * Returns the selected profile name when launcher window closed. + * Returns the selected profile name when the launcher window closed. * - * \return The name of selected profile (this is only the name without file extension - * and without path) + * \return The path to the selected profile */ std::string selectedProfile() const; /** - * Returns the selected sgct window configuration when launcher window closed. + * Returns the selected SGCT window configuration when the launcher window closed. * - * \return The name of selected profile (this is only the name without file extension - * and without path) + * \return The path to the selected profile */ std::string selectedWindowConfig() const; diff --git a/apps/OpenSpace/ext/launcher/include/notificationwindow.h b/apps/OpenSpace/ext/launcher/include/notificationwindow.h new file mode 100644 index 0000000000..fd7007c88f --- /dev/null +++ b/apps/OpenSpace/ext/launcher/include/notificationwindow.h @@ -0,0 +1,42 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2025 * + * * + * 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 __OPENSPACE_UI_LAUNCHER___NOTIFICATIONWINDOW___H__ +#define __OPENSPACE_UI_LAUNCHER___NOTIFICATIONWINDOW___H__ + +#include + +#include +#include + +class NotificationWindow final : public QTextEdit { +Q_OBJECT +public: + explicit NotificationWindow(QWidget* parent); + +private: + std::unique_ptr _request; +}; + +#endif // __OPENSPACE_UI_LAUNCHER___NOTIFICATIONWINDOW___H__ diff --git a/apps/OpenSpace/ext/launcher/include/profile/profileedit.h b/apps/OpenSpace/ext/launcher/include/profile/profileedit.h index 55ea52c6a2..3aa007bfa9 100644 --- a/apps/OpenSpace/ext/launcher/include/profile/profileedit.h +++ b/apps/OpenSpace/ext/launcher/include/profile/profileedit.h @@ -86,16 +86,17 @@ signals: void raiseExitWindow(); private slots: - void openMeta(); void openProperties(); - void openModules(); - void openKeybindings(); void openAssets(); - void openTime(); - void openAddedScripts(); + void openKeybindings(); + void openMeta(); + void openMarkNodes(); void openDeltaTimes(); void openCamera(); - void openMarkNodes(); + void openTime(); + void openModules(); + void openUiPanels(); + void openAddedScripts(); void approved(); private: @@ -112,18 +113,19 @@ private: std::string _profileFilename; QLineEdit* _profileEdit = nullptr; - QLabel* _modulesLabel = nullptr; - QLabel* _assetsLabel = nullptr; - QTextEdit* _assetsEdit = nullptr; QLabel* _propertiesLabel = nullptr; QTextEdit* _propertiesEdit = nullptr; + QLabel* _assetsLabel = nullptr; + QTextEdit* _assetsEdit = nullptr; QLabel* _keybindingsLabel = nullptr; QTextEdit* _keybindingsEdit = nullptr; - QLabel* _deltaTimesLabel = nullptr; + QLabel* _metaLabel = nullptr; QLabel* _interestingNodesLabel = nullptr; + QLabel* _deltaTimesLabel = nullptr; QLabel* _cameraLabel = nullptr; QLabel* _timeLabel = nullptr; - QLabel* _metaLabel = nullptr; + QLabel* _modulesLabel = nullptr; + QLabel* _uiPanelVisibilityLabel = nullptr; QLabel* _additionalScriptsLabel = nullptr; }; diff --git a/apps/OpenSpace/ext/launcher/include/profile/timedialog.h b/apps/OpenSpace/ext/launcher/include/profile/timedialog.h index 13eaf03910..cb08267e1b 100644 --- a/apps/OpenSpace/ext/launcher/include/profile/timedialog.h +++ b/apps/OpenSpace/ext/launcher/include/profile/timedialog.h @@ -30,10 +30,10 @@ #include class QCheckBox; -class QComboBox; class QDateTimeEdit; class QLabel; class QLineEdit; +class QTabWidget; class TimeDialog final : public QDialog { Q_OBJECT @@ -48,18 +48,15 @@ public: TimeDialog(QWidget* parent, std::optional* time); private slots: - void enableAccordingToType(int); void approved(); private: void createWidgets(); - void enableFormatForAbsolute(bool enableAbs); std::optional* _time = nullptr; openspace::Profile::Time _timeData; - bool _initializedAsAbsolute = true; - QComboBox* _typeCombo = nullptr; + QTabWidget* _tabWidget = nullptr; QLabel* _absoluteLabel = nullptr; QDateTimeEdit* _absoluteEdit = nullptr; QLabel* _relativeLabel = nullptr; diff --git a/apps/OpenSpace/ext/launcher/include/profile/uipanelsdialog.h b/apps/OpenSpace/ext/launcher/include/profile/uipanelsdialog.h new file mode 100644 index 0000000000..d6ea979a74 --- /dev/null +++ b/apps/OpenSpace/ext/launcher/include/profile/uipanelsdialog.h @@ -0,0 +1,51 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2025 * + * * + * 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 __OPENSPACE_UI_LAUNCHER___UIPANELSDIALOG___H__ +#define __OPENSPACE_UI_LAUNCHER___UIPANELSDIALOG___H__ + +#include + +class QCheckBox; + +class UiPanelsDialog final : public QDialog { +Q_OBJECT +public: + /** + * Constructor for UiPanelsDialog class. + * + * \param parent Pointer to parent Qt widget + * \param uiPanels The list of ui panels and their visibility + */ + UiPanelsDialog(QWidget* parent, std::map* uiPanels); + +private slots: + void parseSelections(); + +private: + std::map* _uiPanels; + std::map _checkboxToId; +}; + +#endif // __OPENSPACE_UI_LAUNCHER___UIPANELSDIALOG___H__ diff --git a/apps/OpenSpace/ext/launcher/include/sgctedit/windowcontrol.h b/apps/OpenSpace/ext/launcher/include/sgctedit/windowcontrol.h index 4fe3a35baa..cc53ebc80c 100644 --- a/apps/OpenSpace/ext/launcher/include/sgctedit/windowcontrol.h +++ b/apps/OpenSpace/ext/launcher/include/sgctedit/windowcontrol.h @@ -127,9 +127,10 @@ public: * * \param quality The value for number of vertical lines of resolution. This will be * compared against the QualityValues array in order to set the correct - * combobox index + * combobox index + * \tilt The tilt of the fisheye in degrees */ - void setProjectionFisheye(int quality); + void setProjectionFisheye(int quality, float tilt, float fov); /** * Sets the window's projection type to spherical mirror, with the accompanying @@ -162,6 +163,21 @@ public: */ void setProjectionEquirectangular(int quality); + /** + * Sets the window's projection type to blitting the contents of another window. + * + * \param windowBlitId The id of the window from which to blit + */ + void setProjectionBlit(int windowBlitId); + + /** + * This function must be called by users of this class whenever the total number of + * windows has changed. + * + * \param newWindowCount the number of windows after the change + */ + void updateWindowCount(int newWindowCount); + signals: void windowChanged(int monitorIndex, int windowIndex, const QRectF& newDimensions); @@ -171,6 +187,7 @@ private: QWidget* createSphericalMirrorWidget(); QWidget* createCylindricalWidget(); QWidget* createEquirectangularWidget(); + QWidget* createBlitWidget(); void onSizeXChanged(int newValue); void onSizeYChanged(int newValue); @@ -209,44 +226,40 @@ private: struct { QWidget* widget = nullptr; - QLabel* labelInfo = nullptr; QDoubleSpinBox* fovH = nullptr; QDoubleSpinBox* fovV = nullptr; - QLabel* labelFovH = nullptr; - QLabel* labelFovV = nullptr; QPushButton* buttonLockFov = nullptr; } _planar; struct { QWidget* widget = nullptr; - QLabel* labelInfo = nullptr; QComboBox* quality = nullptr; - QLabel* labelQuality = nullptr; + QDoubleSpinBox* tilt = nullptr; + QDoubleSpinBox* fov = nullptr; } _fisheye; struct { QWidget* widget = nullptr; - QLabel* labelInfo = nullptr; QComboBox* quality = nullptr; - QLabel* labelQuality = nullptr; } _sphericalMirror; struct { QWidget* widget = nullptr; - QLabel* labelInfo = nullptr; QComboBox* quality = nullptr; - QLabel* labelQuality = nullptr; QDoubleSpinBox* heightOffset = nullptr; - QLabel* labelHeightOffset = nullptr; } _cylindrical; struct { QWidget* widget = nullptr; - QLabel* labelInfo = nullptr; QComboBox* quality = nullptr; - QLabel* labelQuality = nullptr; } _equirectangular; + struct { + QWidget* widget = nullptr; + QComboBox* windowId = nullptr; + QLabel* unavailable = nullptr; + } _blit; + const QIcon _lockIcon; const QIcon _unlockIcon; }; diff --git a/apps/OpenSpace/ext/launcher/include/usericon.h b/apps/OpenSpace/ext/launcher/include/usericon.h new file mode 100644 index 0000000000..de08e80e2b --- /dev/null +++ b/apps/OpenSpace/ext/launcher/include/usericon.h @@ -0,0 +1,28 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2025 * + * * + * 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 + +// Creates an icon that is used to represent user-generated content +QIcon userIcon(); diff --git a/apps/OpenSpace/ext/launcher/resources/qss/launcher.qss b/apps/OpenSpace/ext/launcher/resources/qss/launcher.qss index b9b1ed9fef..0847382e6f 100644 --- a/apps/OpenSpace/ext/launcher/resources/qss/launcher.qss +++ b/apps/OpenSpace/ext/launcher/resources/qss/launcher.qss @@ -27,7 +27,7 @@ LauncherWindow QLabel { } LauncherWindow QLabel#label_choose, QLabel#label_options { - color: rgb(255, 255, 255); + color: white; font-size: 10pt; } @@ -37,11 +37,11 @@ LauncherWindow QLabel#clear { LauncherWindow QLabel#version-info { font-size: 10pt; - color: #dfdfdf; + color: rgb(225, 225, 225); } LauncherWindow QComboBox#config { - background: rgb(86, 86, 86); + background: rgb(96, 96, 96); border: 1px solid rgb(225, 225, 225); border-radius: 2px; padding: 1px 18px 1px 3px; @@ -49,7 +49,7 @@ LauncherWindow QComboBox#config { font-size: 10pt; font-family: Segoe UI; font-weight: bold; - color: rgb(255, 255, 255); + color: white; } LauncherWindow QComboBox#config:hover { @@ -61,6 +61,17 @@ LauncherWindow QComboBox#config:disabled { color: rgb(225, 225, 225); } +LauncherWindow QMenu#newprofile { + background: rgb(60, 60, 60); + min-width: 8em; + max-width: 8em; + color: white; +} + +LauncherWindow QMenu#newprofile::item:selected { + background: rgb(110, 110, 110); +} + LauncherWindow QPushButton#start { background: rgb(96, 96, 96); border: 2px solid rgb(225, 225, 225); @@ -69,34 +80,34 @@ LauncherWindow QPushButton#start { font-size: 16pt; font-weight: bold; letter-spacing: 1px; - color: rgb(255, 255, 255); + color: white; } LauncherWindow QPushButton#start:hover { - background: rgb(120, 120, 120); + background: rgb(110, 110, 110); } LauncherWindow QPushButton#start:disabled { - background: rgb(175, 175, 175); - color: rgb(225, 225, 225); + background: rgb(60, 60, 60); + border: 1px solid rgb(60, 60, 60); + color: rgb(90, 90, 90); } LauncherWindow QPushButton#small { - background: rgb(86, 86, 86); + background: rgb(90, 90, 90); border: 1px solid rgb(225, 225, 225); border-radius: 2px; border-style: outset; min-height: 1em; font-size: 10pt; font-weight: bold; - color: rgb(255, 255, 255); + color: white; } - LauncherWindow QPushButton#small:hover { background: rgb(110, 110, 110); } - LauncherWindow QPushButton#small:disabled { - background: rgb(204, 204, 204); - color: rgb(86, 86, 86); + background: rgb(60, 60, 60); + border: 1px solid rgb(60, 60, 60); + color: rgb(90, 90, 90); } LauncherWindow QPushButton#settings { @@ -119,6 +130,12 @@ LauncherWindow QComboBox#config:focus LauncherWindow QPushButton#settings:focus { outline: 2px solid rgb(61, 189, 238); } + +LauncherWindow QTextEdit#notifications { + background-color: #242424; + color: #d7d7d7; +} + /* * ProfileEdit */ @@ -195,6 +212,10 @@ ScriptlogDialog QListWidget { min-width: 60em; } +MarkNodesDialog QListWidget:focus { + border: 2px solid rgb(61, 189, 238); +} + /* * Horizons dialog */ @@ -211,7 +232,7 @@ HorizonsDialog QLabel#thin { } HorizonsDialog QLabel#normal { - color: rgb(0, 0, 0); + color: black; } /* diff --git a/apps/OpenSpace/ext/launcher/src/launcherwindow.cpp b/apps/OpenSpace/ext/launcher/src/launcherwindow.cpp index 2b9750e089..a5e9f0d0a2 100644 --- a/apps/OpenSpace/ext/launcher/src/launcherwindow.cpp +++ b/apps/OpenSpace/ext/launcher/src/launcherwindow.cpp @@ -26,6 +26,7 @@ #include "profile/profileedit.h" #include "backgroundimage.h" +#include "notificationwindow.h" #include "settingsdialog.h" #include "splitcombobox.h" #include @@ -35,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -45,8 +47,10 @@ using namespace openspace; namespace { - constexpr int ScreenWidth = 480; - constexpr int ScreenHeight = 640; + constexpr int MainScreenWidth = 480; + constexpr int MainScreenHeight = 640; + constexpr int FullScreenWidth = MainScreenWidth; + constexpr int FullScreenHeight = 706; constexpr int LeftRuler = 40; constexpr int TopRuler = 80; @@ -55,10 +59,12 @@ namespace { constexpr int SmallItemWidth = 100; constexpr int SmallItemHeight = SmallItemWidth / 4; + constexpr int NotificationShelfHeight = FullScreenHeight - MainScreenHeight; + constexpr int SettingsIconSize = 35; namespace geometry { - constexpr QRect BackgroundImage(0, 0, ScreenWidth, ScreenHeight); + constexpr QRect BackgroundImage(0, 0, MainScreenWidth, MainScreenHeight); constexpr QRect LogoImage(LeftRuler, TopRuler, ItemWidth, ItemHeight); constexpr QRect ChooseLabel(LeftRuler + 10, TopRuler + 80, 151, 24); constexpr QRect ProfileBox(LeftRuler, TopRuler + 110, ItemWidth, ItemHeight); @@ -80,14 +86,19 @@ namespace { LeftRuler, TopRuler + 400, ItemWidth, ItemHeight ); constexpr QRect VersionString( - 5, ScreenHeight - SmallItemHeight, ItemWidth, SmallItemHeight + 5, MainScreenHeight - SmallItemHeight, ItemWidth, SmallItemHeight ); constexpr QRect SettingsButton( - ScreenWidth - SettingsIconSize - 5, - ScreenHeight - SettingsIconSize - 5, + MainScreenWidth - SettingsIconSize - 5, + MainScreenHeight - SettingsIconSize - 5, SettingsIconSize, SettingsIconSize ); + constexpr QRect NotificationShelf( + 0, + MainScreenHeight, + MainScreenWidth, + NotificationShelfHeight); } // namespace geometry @@ -132,7 +143,7 @@ LauncherWindow::LauncherWindow(bool profileEnabled, const Configuration& globalC ); setWindowTitle("OpenSpace Launcher"); - setFixedSize(ScreenWidth, ScreenHeight); + setFixedSize(FullScreenWidth, FullScreenHeight); setAutoFillBackground(false); { @@ -163,6 +174,12 @@ LauncherWindow::LauncherWindow(bool profileEnabled, const Configuration& globalC logoImage->setPixmap(QPixmap(":/images/openspace-horiz-logo-small.png")); } + { + NotificationWindow* notificationWindow = new NotificationWindow(centralWidget); + notificationWindow->setGeometry(geometry::NotificationShelf); + notificationWindow->show(); + } + // // Profile chooser // @@ -173,30 +190,6 @@ LauncherWindow::LauncherWindow(bool profileEnabled, const Configuration& globalC labelChoose->setObjectName("label_choose"); } - _editProfileButton = new QPushButton("Edit", centralWidget); - _editProfileButton->setObjectName("small"); - _editProfileButton->setGeometry(geometry::EditProfileButton); - _editProfileButton->setCursor(Qt::PointingHandCursor); - _editProfileButton->setAutoDefault(true); - _editProfileButton->setAccessibleName("Edit profile"); - connect( - _editProfileButton, &QPushButton::released, - this, &LauncherWindow::editProfile - ); - - { - QPushButton* newProfileButton = new QPushButton("New", centralWidget); - newProfileButton->setObjectName("small"); - newProfileButton->setGeometry(geometry::NewProfileButton); - newProfileButton->setCursor(Qt::PointingHandCursor); - newProfileButton->setAutoDefault(true); - newProfileButton->setAccessibleName("New profile"); - connect( - newProfileButton, &QPushButton::released, - this, &LauncherWindow::newProfile - ); - } - // Creating the profile box _after_ the Edit and New buttons as the comboboxes // `selectionChanged` signal will trigger that will try to make changes to the edit // button @@ -222,8 +215,8 @@ LauncherWindow::LauncherWindow(bool profileEnabled, const Configuration& globalC _profileBox->setObjectName("config"); _profileBox->setGeometry(geometry::ProfileBox); _profileBox->setAccessibleName("Choose profile"); - _profileBox->populateList(globalConfig.profile); _profileBox->setEnabled(profileEnabled); + _profileBox->populateList(globalConfig.profile); connect( _profileBox, &SplitComboBox::selectionChanged, this, &LauncherWindow::selectProfile @@ -233,12 +226,58 @@ LauncherWindow::LauncherWindow(bool profileEnabled, const Configuration& globalC this, &LauncherWindow::updateStartButton ); + + _editProfileButton = new QPushButton("Edit", centralWidget); + _editProfileButton->setObjectName("small"); + _editProfileButton->setGeometry(geometry::EditProfileButton); + _editProfileButton->setCursor(Qt::PointingHandCursor); + _editProfileButton->setAutoDefault(true); + _editProfileButton->setAccessibleName("Edit profile"); + connect( + _editProfileButton, &QPushButton::released, + this, &LauncherWindow::editProfile + ); { // Set up the default value for the edit button std::string selection = std::get<1>(_profileBox->currentSelection()); _editProfileButton->setEnabled(std::filesystem::exists(selection)); } + { + QPushButton* newProfileButton = new QPushButton("New", centralWidget); + newProfileButton->setObjectName("small"); + newProfileButton->setGeometry(geometry::NewProfileButton); + newProfileButton->setCursor(Qt::PointingHandCursor); + newProfileButton->setAutoDefault(true); + newProfileButton->setAccessibleName("New profile"); + connect( + newProfileButton, &QPushButton::released, + this, &LauncherWindow::newProfile + ); + + QMenu* menu = new QMenu(this); + menu->setObjectName("newprofile"); + menu->setToolTipsVisible(true); + QAction* newEmpty = new QAction("Empty profile", this); + newEmpty->setToolTip("Creates a new empty profile without any existing content"); + connect( + newEmpty, &QAction::triggered, + this, &LauncherWindow::newProfile + ); + QAction* newFromCurrent = new QAction("Duplicate profile", this); + newFromCurrent->setToolTip( + "Creates a duplicate of the currently selected profile. This duplicate can " + "be edited and saved under a new name, or if it was a user profile be " + "overwritten" + ); + connect( + newFromCurrent, &QAction::triggered, + this, &LauncherWindow::editProfile + ); + menu->addActions({ newEmpty, newFromCurrent }); + newProfileButton->setMenu(menu); + } + // @@ -250,31 +289,6 @@ LauncherWindow::LauncherWindow(bool profileEnabled, const Configuration& globalC optionsLabel->setObjectName("label_options"); } - _editWindowButton = new QPushButton("Edit", centralWidget); - _editWindowButton->setVisible(true); - _editWindowButton->setObjectName("small"); - _editWindowButton->setGeometry(geometry::EditWindowButton); - _editWindowButton->setCursor(Qt::PointingHandCursor); - _editWindowButton->setAutoDefault(true); - _editWindowButton->setAccessibleName("Edit window configuration"); - connect( - _editWindowButton, &QPushButton::released, - this, &LauncherWindow::editConfiguration - ); - - { - QPushButton* newWindowButton = new QPushButton("New", centralWidget); - newWindowButton->setObjectName("small"); - newWindowButton->setGeometry(geometry::NewWindowButton); - newWindowButton->setCursor(Qt::PointingHandCursor); - newWindowButton->setAutoDefault(true); - newWindowButton->setAccessibleName("New window configuration"); - connect( - newWindowButton, &QPushButton::released, - this, &LauncherWindow::newConfiguration - ); - } - _windowConfigBox = new SplitComboBox( centralWidget, _userConfigPath, @@ -313,11 +327,36 @@ LauncherWindow::LauncherWindow(bool profileEnabled, const Configuration& globalC this, &LauncherWindow::updateStartButton ); + + + _editWindowButton = new QPushButton("Edit", centralWidget); + _editWindowButton->setVisible(true); + _editWindowButton->setObjectName("small"); + _editWindowButton->setGeometry(geometry::EditWindowButton); + _editWindowButton->setCursor(Qt::PointingHandCursor); + _editWindowButton->setAutoDefault(true); + _editWindowButton->setAccessibleName("Edit window configuration"); + connect( + _editWindowButton, &QPushButton::released, + this, &LauncherWindow::editConfiguration + ); { // Set up the default value for the edit button std::string selection = std::get<1>(_windowConfigBox->currentSelection()); _editWindowButton->setEnabled(std::filesystem::exists(selection)); } + { + QPushButton* newWindowButton = new QPushButton("New", centralWidget); + newWindowButton->setObjectName("small"); + newWindowButton->setGeometry(geometry::NewWindowButton); + newWindowButton->setCursor(Qt::PointingHandCursor); + newWindowButton->setAutoDefault(true); + newWindowButton->setAccessibleName("New window configuration"); + connect( + newWindowButton, &QPushButton::released, + this, &LauncherWindow::newConfiguration + ); + } // @@ -343,9 +382,7 @@ LauncherWindow::LauncherWindow(bool profileEnabled, const Configuration& globalC { QLabel* versionLabel = new QLabel(centralWidget); versionLabel->setVisible(true); - versionLabel->setText( - QString::fromStdString(std::string(OPENSPACE_VERSION_STRING_FULL)) - ); + versionLabel->setText(QString::fromStdString(std::string(OPENSPACE_VERSION))); versionLabel->setObjectName("version-info"); versionLabel->setGeometry(geometry::VersionString); } @@ -391,7 +428,19 @@ void LauncherWindow::selectProfile(std::optional selection) { ghoul_assert(selection.has_value(), "No special item in the profiles"); if (selection.has_value()) { // Having the `if` statement here to satisfy the MSVC code analysis - _editProfileButton->setEnabled(std::filesystem::exists(*selection)); + + // Enable the Edit button only for the user profiles + const bool isUser = selection->starts_with(_userProfilePath.string()); + _editProfileButton->setEnabled(isUser); + + if (isUser) { + _editProfileButton->setToolTip(""); + } + else { + _editProfileButton->setToolTip( + "Cannot edit the selected profile as it is one of the built-in profiles" + ); + } } } @@ -407,8 +456,7 @@ void LauncherWindow::selectConfiguration(std::optional selection) { // If the configuration is a default configuration, we don't allow editing _editWindowButton->setEnabled(false); _editWindowButton->setToolTip( - "Cannot edit since the selected configuration is one of the files " - "provided by OpenSpace" + "Cannot edit the selected configuration as it is one of the built-in profiles" ); } else { @@ -453,7 +501,7 @@ void LauncherWindow::editConfiguration() { assert(cluster.generator); std::string err = sgct::validateConfigAgainstSchema( - path, + std::filesystem::path(path), _configPath / "schema/sgct.schema.json" ); if (!err.empty()) { @@ -598,19 +646,21 @@ void LauncherWindow::openProfileEditor(const std::string& profile, bool isUserPr &ProfileEdit::raiseExitWindow, [&editor, &savePath, &p, &profile]() { const std::string origPath = std::format("{}{}.profile", savePath, profile); - // If this is a new profile we want to prompt the user - if (!std::filesystem::exists(origPath)) { + // If this is a new profile we want to prompt the user, but only if the user + // actually changed something. If it is still an empty profile, there is no + // need to save it + if (!std::filesystem::exists(origPath) && *p != Profile()) { + editor.promptUserOfUnsavedChanges(); + return; + } + // Check if the profile is the same as current existing file + if (std::filesystem::exists(origPath) && *p != Profile(origPath)) { editor.promptUserOfUnsavedChanges(); return; } - // Check if the profile is the same as current existing file - if (*p != Profile(origPath)) { - editor.promptUserOfUnsavedChanges(); - } - else { - editor.closeWithoutSaving(); - } + // If we got this far, we can safely close the dialog without saving anything + editor.closeWithoutSaving(); } ); diff --git a/apps/OpenSpace/ext/launcher/src/notificationwindow.cpp b/apps/OpenSpace/ext/launcher/src/notificationwindow.cpp new file mode 100644 index 0000000000..02c4420488 --- /dev/null +++ b/apps/OpenSpace/ext/launcher/src/notificationwindow.cpp @@ -0,0 +1,231 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2025 * + * * + * 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 "notificationwindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace openspace; + +namespace { + struct Entry { + std::string date; + std::string text; + }; + + // Parses a single notification entry out of the list of lines + Entry parseEntry(std::vector::const_iterator& curr) { + ghoul_assert(!curr->empty(), "First line must not be empty"); + + std::string date = *curr; + std::string text; + do { + curr++; + + text += *curr; + } while (!curr->empty()); + curr++; + + return { std::move(date), std::move(text) }; + } + + std::vector parseEntries(const std::string& data) { + std::vector entries; + + std::vector lines = ghoul::tokenizeString(data, '\n'); + if (lines.empty() || lines[0].empty()) { + // The notification file is empty and we don't want to show anything + return entries; + } + + std::vector::const_iterator curr = lines.cbegin(); + while (curr != lines.end()) { + Entry e = parseEntry(curr); + entries.push_back(std::move(e)); + } + + return entries; + } + + std::string formatEntry(const Entry& e, date::year_month_day lastStartedDate) { + auto r = scn::scan(e.date, "{}-{}-{}"); + ghoul_assert(r, "Invalid date"); + auto& [year, month, day] = r->values(); + const date::year_month_day ymd = date::year_month_day( + date::year(year), + date::month(month), + date::day(day) + ); + + QColor text = QGuiApplication::palette().text().color(); + text = text.darker(); + + if (date::sys_days(ymd) < date::sys_days(lastStartedDate)) { + const QColor textColor = QColor(120, 120, 120); + return std::format( + "" + "" + "{0}" + "" + "" + "{1}" + "" + "", + e.date, e.text, textColor.red(), textColor.green(), textColor.blue() + ); + } + else { + return std::format( + "" + "" + "{0}" + "" + "" + "{1}" + "" + "", + e.date, e.text + ); + } + } +} // namespace + +NotificationWindow::NotificationWindow(QWidget* parent) + : QTextEdit(parent) +{ + setAcceptRichText(true); + setReadOnly(true); + setFocusPolicy(Qt::NoFocus); + setObjectName("notifications"); + + std::string URL = std::format( + "https://raw.githubusercontent.com/OpenSpace/Notifications/refs/heads/master/" + "{}.txt", + OPENSPACE_IS_RELEASE_BUILD ? OPENSPACE_VERSION : "master" + ); + + _request = std::make_unique( + URL, + ghoul::logging::LogLevel::NoLogging + ); + _request->start(std::chrono::seconds(1)); + + // The download has a timeout of 1s, so after 1250ms we'll definitely have answer. + constexpr int TimeOut = 1250; + QTimer::singleShot(TimeOut, [this](){ + while (!_request->hasSucceeded() && !_request->hasFailed()) { + std::this_thread::sleep_for(std::chrono::milliseconds(250)); + } + if (_request->hasFailed()) { + LWARNINGC("Notification", "Failed to retrieve notification file"); + // The download has failed for some reason + return; + } + + // 1. Get the downloaded data + const std::vector& data = _request->downloadedData(); + std::string notificationText = std::string(data.begin(), data.end()); + + // 2. Parse the retrieved data into entries + std::vector entries = parseEntries(notificationText); + + // 3. Filter the entries to not show anything that is older than 6 months + const date::year_month_day now = date::year_month_day( + floor(std::chrono::system_clock::now()) + ); + std::erase_if( + entries, + [now](const Entry& e) { + auto r = scn::scan(e.date, "{}-{}-{}"); + if (!r) { + return false; + } + + auto& [year, month, day] = r->values(); + + const date::year_month_day ymd = date::year_month_day( + date::year(year), + date::month(month), + date::day(day) + ); + + const std::chrono::days diff = date::sys_days(now) - date::sys_days(ymd); + const bool older = diff.count() > (365 / 2); + return older; + } + ); + + // 4. Format the entries into a table format + Settings settings = loadSettings(); + // Picking a date as the default date that is far enough in the past + date::year_month_day lastStart = date::year_month_day( + date::year(2000), + date::month(1), + date::day(1) + ); + if (settings.lastStartedDate.has_value()) { + auto r = scn::scan(*settings.lastStartedDate, "{}-{}-{}"); + if (r) { + auto& [year, month, day] = r->values(); + + lastStart = date::year_month_day( + date::year(year), + date::month(month), + date::day(day) + ); + } + } + + std::string text = std::accumulate( + entries.begin(), + entries.end(), + std::string(), + [&lastStart](std::string t, const Entry& e) { + return std::format( + "{}{}", + std::move(t), formatEntry(e, lastStart) + ); + } + ); + + // Add the HTML-like table attributes + text = std::format("{}
", std::move(text)); + + // 5. Set the text + QString t = QString::fromStdString(text); + setText(t); + }); +} diff --git a/apps/OpenSpace/ext/launcher/src/profile/assettreemodel.cpp b/apps/OpenSpace/ext/launcher/src/profile/assettreemodel.cpp index 06e6baa82a..bb250d98d1 100644 --- a/apps/OpenSpace/ext/launcher/src/profile/assettreemodel.cpp +++ b/apps/OpenSpace/ext/launcher/src/profile/assettreemodel.cpp @@ -298,7 +298,9 @@ QVariant AssetTreeModel::data(const QModelIndex& index, int role) const { } if (role == Qt::ForegroundRole) { - return item->doesExistInFilesystem() ? QColor(Qt::black) : QColor(Qt::red); + // Returning an empty variant will cause Qt to use the theme-appropriate color for + // the item + return item->doesExistInFilesystem() ? QVariant() : QColor(Qt::red); } else if (role == Qt::DisplayRole) { return item->data(index.column()); diff --git a/apps/OpenSpace/ext/launcher/src/profile/horizonsdialog.cpp b/apps/OpenSpace/ext/launcher/src/profile/horizonsdialog.cpp index ee400d30bb..edc387af6b 100644 --- a/apps/OpenSpace/ext/launcher/src/profile/horizonsdialog.cpp +++ b/apps/OpenSpace/ext/launcher/src/profile/horizonsdialog.cpp @@ -917,7 +917,7 @@ openspace::HorizonsFile HorizonsDialog::handleAnswer(nlohmann::json& answer) { } // Return a new file with the result - return openspace::HorizonsFile(filePath, *result); + return openspace::HorizonsFile(filePath, result->get()); } bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) { @@ -1084,6 +1084,23 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) { std::filesystem::remove(_horizonsFile.file()); break; } + case HorizonsResultCode::News: { + std::string msg = std::format( + "The target '{}' is too simlar to the Horizons command 'NEWS'", + _targetName + ); + appendLog(msg, HorizonsDialog::LogLevel::Error); + + msg = std::format( + "Try to use '@{}' as target to avoid false positive matches with the " + "Horizons command 'NEWS'", _targetName + ); + appendLog(msg, HorizonsDialog::LogLevel::Info); + styleLabel(_targetLabel, IsDirty::Yes); + + std::filesystem::remove(_horizonsFile.file()); + break; + } case HorizonsResultCode::MultipleObserver: { std::string msg = std::format( "Multiple matches were found for observer '{}'", _observerName diff --git a/apps/OpenSpace/ext/launcher/src/profile/profileedit.cpp b/apps/OpenSpace/ext/launcher/src/profile/profileedit.cpp index 6d39cb20ed..1b562035f6 100644 --- a/apps/OpenSpace/ext/launcher/src/profile/profileedit.cpp +++ b/apps/OpenSpace/ext/launcher/src/profile/profileedit.cpp @@ -35,6 +35,7 @@ #include "profile/modulesdialog.h" #include "profile/propertiesdialog.h" #include "profile/timedialog.h" +#include "profile/uipanelsdialog.h" #include #include #include @@ -305,6 +306,21 @@ void ProfileEdit::createWidgets() { rightLayout->addLayout(container); } rightLayout->addWidget(new Line); + { + QBoxLayout* container = new QVBoxLayout; + _uiPanelVisibilityLabel = new QLabel("User Interface Panels"); + _uiPanelVisibilityLabel->setObjectName("heading"); + _uiPanelVisibilityLabel->setWordWrap(true); + container->addWidget(_uiPanelVisibilityLabel); + + QPushButton* uiPanelEdit = new QPushButton("Edit"); + connect(uiPanelEdit, &QPushButton::clicked, this, &ProfileEdit::openUiPanels); + uiPanelEdit->setLayoutDirection(Qt::RightToLeft); + uiPanelEdit->setAccessibleName("Edit user interface panels"); + container->addWidget(uiPanelEdit); + rightLayout->addLayout(container); + } + rightLayout->addWidget(new Line); { QBoxLayout* container = new QVBoxLayout; _additionalScriptsLabel = new QLabel("Additional Scripts"); @@ -375,6 +391,10 @@ void ProfileEdit::openModules() { _modulesLabel->setText(labelText(_profile.modules.size(), "Modules")); } +void ProfileEdit::openUiPanels() { + UiPanelsDialog(this, &_profile.uiPanelVisibility).exec(); +} + void ProfileEdit::openProperties() { PropertiesDialog(this, &_profile.properties).exec(); _propertiesLabel->setText(labelText(_profile.properties.size(), "Properties")); diff --git a/apps/OpenSpace/ext/launcher/src/profile/propertiesdialog.cpp b/apps/OpenSpace/ext/launcher/src/profile/propertiesdialog.cpp index f0503b2b70..59ff2ebcd0 100644 --- a/apps/OpenSpace/ext/launcher/src/profile/propertiesdialog.cpp +++ b/apps/OpenSpace/ext/launcher/src/profile/propertiesdialog.cpp @@ -409,10 +409,22 @@ void PropertiesDialog::selectLineFromScriptLog() { } // Remove the string markers around the property - const QString property = textList[0].mid(1, textList[0].size() - 2); - const QString value = textList[1]; + const QString prop = textList[0].mid(1, textList[0].size() - 2).trimmed(); - _propertyEdit->setText(property.trimmed()); + QString value = textList[1].trimmed(); + // If they exist, we need to replace the single string markers around the + // property, with double string markers + if (value.size() > 2) { + if (value[0] == '\'') { + value[0] = '"'; + } + const QChar end = value[value.size() - 1]; + if (value[value.size() - 1] == '\'') { + value[value.size() - 1] = '"'; + } + } + + _propertyEdit->setText(prop); _valueEdit->setText(value.trimmed()); listItemSave(); } diff --git a/apps/OpenSpace/ext/launcher/src/profile/timedialog.cpp b/apps/OpenSpace/ext/launcher/src/profile/timedialog.cpp index 22be9609f9..a1c86a2f7b 100644 --- a/apps/OpenSpace/ext/launcher/src/profile/timedialog.cpp +++ b/apps/OpenSpace/ext/launcher/src/profile/timedialog.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -45,8 +46,6 @@ TimeDialog::TimeDialog(QWidget* parent, std::optional* setWindowTitle("Time"); createWidgets(); - const QStringList types = { "Absolute", "Relative" }; - _typeCombo->addItems(types); if (_time->has_value()) { _timeData = **_time; if (_timeData.type == Profile::Time::Type::Relative) { @@ -66,44 +65,75 @@ TimeDialog::TimeDialog(QWidget* parent, std::optional* } _startPaused->setChecked(_timeData.startPaused); - _initializedAsAbsolute = (_timeData.type == Profile::Time::Type::Absolute); - enableAccordingToType(static_cast(_timeData.type)); + if (_timeData.type == Profile::Time::Type::Relative) { + _relativeEdit->setText(QString::fromStdString(_timeData.value)); + _relativeEdit->setFocus(Qt::OtherFocusReason); + } + else { + const size_t tIdx = _timeData.value.find_first_of('T', 0); + const QString importDate = QString::fromStdString( + _timeData.value.substr(0, tIdx) + ); + const QString importTime = QString::fromStdString( + _timeData.value.substr(tIdx + 1) + ); + _absoluteEdit->setDate(QDate::fromString(importDate, Qt::DateFormat::ISODate)); + _absoluteEdit->setTime(QTime::fromString(importTime)); + _relativeEdit->clear(); + _absoluteEdit->setFocus(Qt::OtherFocusReason); + } + + _tabWidget->setCurrentIndex(static_cast(_timeData.type)); } void TimeDialog::createWidgets() { QBoxLayout* layout = new QVBoxLayout(this); + + _tabWidget = new QTabWidget; + { - layout->addWidget(new QLabel("Time Type")); - _typeCombo = new QComboBox; - _typeCombo->setAccessibleName("Time type"); - _typeCombo->setToolTip("Types: Absolute defined time or Relative to actual time"); - connect( - _typeCombo, QOverload::of(&QComboBox::currentIndexChanged), - this, &TimeDialog::enableAccordingToType - ); - layout->addWidget(_typeCombo); - } - { + QWidget* container = new QWidget; + QBoxLayout* l = new QVBoxLayout(container); _absoluteLabel = new QLabel("Absolute UTC:"); - layout->addWidget(_absoluteLabel); + l->addWidget(_absoluteLabel); _absoluteEdit = new QDateTimeEdit; _absoluteEdit->setDisplayFormat("yyyy-MM-dd T hh:mm:ss"); _absoluteEdit->setDateTime(QDateTime::currentDateTime()); _absoluteEdit->setAccessibleName("Set absolute time"); - layout->addWidget(_absoluteEdit); + l->addWidget(_absoluteEdit); + + l->addStretch(); + + _tabWidget->addTab(container, "Absolute"); } { + QWidget* container = new QWidget; + QBoxLayout* l = new QVBoxLayout(container); _relativeLabel = new QLabel("Relative Time:"); - layout->addWidget(_relativeLabel); + l->addWidget(_relativeLabel); _relativeEdit = new QLineEdit; _relativeEdit->setAccessibleName("Set relative time"); _relativeEdit->setToolTip( "String for relative time to actual (e.g. \"-1d\" for back 1 day)" ); - layout->addWidget(_relativeEdit); + l->addWidget(_relativeEdit); + + QLabel* desc = new QLabel( + "This field modifies the default start time. It has to be of the form " + "[-]XX(s,m,h,d,M,y). For example '-1d' will cause the profile to start at " + "yesterday's date." + ); + desc->setObjectName("information"); + desc->setWordWrap(true); + l->addWidget(desc); + + _tabWidget->addTab(container, "Relative"); } + + layout->addWidget(_tabWidget); + { _startPaused = new QCheckBox("Start with time paused"); _startPaused->setChecked(false); @@ -123,47 +153,9 @@ void TimeDialog::createWidgets() { } } -void TimeDialog::enableAccordingToType(int idx) { - const Profile::Time::Type comboIdx = static_cast(idx); - const bool setFormatForAbsolute = (comboIdx == Profile::Time::Type::Absolute); - enableFormatForAbsolute(setFormatForAbsolute); - _typeCombo->setCurrentIndex(idx); - if (comboIdx == Profile::Time::Type::Relative) { - _relativeEdit->setText("Relative Time:"); - if (_initializedAsAbsolute) { - _relativeEdit->setText("0d"); - } - else { - _relativeEdit->setText(QString::fromStdString(_timeData.value)); - } - _relativeEdit->setFocus(Qt::OtherFocusReason); - } - else { - _relativeEdit->setText("Relative Time:"); - const size_t tIdx = _timeData.value.find_first_of('T', 0); - const QString importDate = QString::fromStdString( - _timeData.value.substr(0, tIdx) - ); - const QString importTime = QString::fromStdString( - _timeData.value.substr(tIdx + 1) - ); - _absoluteEdit->setDate(QDate::fromString(importDate, Qt::DateFormat::ISODate)); - _absoluteEdit->setTime(QTime::fromString(importTime)); - _relativeEdit->clear(); - _absoluteEdit->setFocus(Qt::OtherFocusReason); - } -} - -void TimeDialog::enableFormatForAbsolute(bool enableAbs) { - _absoluteLabel->setEnabled(enableAbs); - _absoluteEdit->setEnabled(enableAbs); - _relativeLabel->setEnabled(!enableAbs); - _relativeEdit->setEnabled(!enableAbs); -} - void TimeDialog::approved() { constexpr int Relative = static_cast(Profile::Time::Type::Relative); - if (_typeCombo->currentIndex() == Relative) { + if (_tabWidget->currentIndex() == Relative) { if (_relativeEdit->text().isEmpty()) { *_time = std::nullopt; } diff --git a/apps/OpenSpace/ext/launcher/src/profile/uipanelsdialog.cpp b/apps/OpenSpace/ext/launcher/src/profile/uipanelsdialog.cpp new file mode 100644 index 0000000000..38d3f38e04 --- /dev/null +++ b/apps/OpenSpace/ext/launcher/src/profile/uipanelsdialog.cpp @@ -0,0 +1,130 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2025 * + * * + * 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 "profile/uipanelsdialog.h" + +#include "profile/line.h" +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { + constexpr std::string_view DefaultPanelPath = "${DATA}/web/default_ui_panels.json"; + + struct Panel { + std::string id; + std::string name; + bool isVisible; + }; + + void from_json(const nlohmann::json& j, Panel& layout) { + j["id"].get_to(layout.id); + j["name"].get_to(layout.name); + j["visible"].get_to(layout.isVisible); + } + + std::vector loadPanels() { + std::ifstream panelFile = std::ifstream(absPath(DefaultPanelPath)); + const std::string panelContent = std::string( + std::istreambuf_iterator(panelFile), + std::istreambuf_iterator() + ); + const nlohmann::json panel = nlohmann::json::parse(panelContent); + std::map panels = panel.get>(); + + std::vector result; + for (const auto& [key, value] : panels) { + result.push_back(value); + } + + std::sort( + result.begin(), + result.end(), + [](const Panel& lhs, const Panel& rhs) { return lhs.name < rhs.name; } + ); + + return result; + } +} // namespace + +UiPanelsDialog::UiPanelsDialog(QWidget* parent, std::map* uiPanels) + : QDialog(parent) + , _uiPanels(uiPanels) +{ + setWindowTitle("User Interface Panels"); + + std::vector panels = loadPanels(); + + QBoxLayout* layout = new QVBoxLayout(this); + + QLabel* info = new QLabel( + "Select the user interface panels that should be visible by default in the " + "current profile." + ); + info->setWordWrap(true); + layout->addWidget(info); + + for (const Panel& panel : panels) { + QCheckBox* box = new QCheckBox(QString::fromStdString(panel.name)); + + // If the profile already has a desired value for the checkbox, use it. Otherwise + // use the default values + auto it = _uiPanels->find(panel.id); + if (it != _uiPanels->end()) { + box->setChecked(it->second); + } + else { + box->setChecked(panel.isVisible); + } + + layout->addWidget(box); + _checkboxToId[box] = panel.id; + } + + layout->addWidget(new Line); + + { + QDialogButtonBox* buttons = new QDialogButtonBox; + buttons->setStandardButtons(QDialogButtonBox::Save | QDialogButtonBox::Cancel); + connect( + buttons, &QDialogButtonBox::accepted, + this, &UiPanelsDialog::parseSelections + ); + connect(buttons, &QDialogButtonBox::rejected, this, &UiPanelsDialog::reject); + layout->addWidget(buttons); + } +} + +void UiPanelsDialog::parseSelections() { + _uiPanels->clear(); + for (const auto& [key, value] : _checkboxToId) { + _uiPanels->emplace(value, key->isChecked()); + } + accept(); +} diff --git a/apps/OpenSpace/ext/launcher/src/settingsdialog.cpp b/apps/OpenSpace/ext/launcher/src/settingsdialog.cpp index 0dc036a102..5e943f99c3 100644 --- a/apps/OpenSpace/ext/launcher/src/settingsdialog.cpp +++ b/apps/OpenSpace/ext/launcher/src/settingsdialog.cpp @@ -55,8 +55,8 @@ void SettingsDialog::createWidgets() { // | Profile | // | Starting Profile: | [oooooooooooooooooooo] | // | [] Keep Last Profile | - // | Configuration | - // | Starting Configuration: | [oooooooooooooooooooo] | + // | Window Options | + // | Starting Window Option: | [oooooooooooooooooooo] | // | [] Keep Last Configuration | // | User Interface | // | Property Visibility | DDDDDDDDDDDDDDDDDDDDD> | @@ -108,9 +108,14 @@ void SettingsDialog::createWidgets() { "If this setting is checked, the application will remember the profile that " "was loaded into OpenSpace and will use it at the next startup as well" ); + connect( _rememberLastProfile, +#if (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)) + &QCheckBox::checkStateChanged, +#else // ^^^^ >=6.7.0 // !WIN32 <6.7.0 &QCheckBox::stateChanged, +#endif // (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)) [this]() { if (_rememberLastProfile->isChecked()) { _currentEdit.rememberLastProfile = true; @@ -129,11 +134,11 @@ void SettingsDialog::createWidgets() { layout->addWidget(new Line(), 3, 0, 1, 2); { - QLabel* label = new QLabel("Configuration"); + QLabel* label = new QLabel("Window Configuration"); label->setObjectName("heading"); layout->addWidget(label, 4, 0, 1, 2); - QLabel* conf = new QLabel("Starting Configuration"); + QLabel* conf = new QLabel("Starting Window Configuration"); conf->setToolTip( "With this setting, you can choose a window configuration that will be " "loaded the next time you start the application" @@ -166,7 +171,11 @@ void SettingsDialog::createWidgets() { ); connect( _rememberLastConfiguration, +#if (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)) + &QCheckBox::checkStateChanged, +#else // ^^^^ >=6.7.0 // !WIN32 <6.7.0 &QCheckBox::stateChanged, +#endif // (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)) [this]() { if (_rememberLastConfiguration->isChecked()) { _currentEdit.rememberLastConfiguration = true; @@ -241,7 +250,11 @@ void SettingsDialog::createWidgets() { ); connect( _bypassLauncher, +#if (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)) + &QCheckBox::checkStateChanged, +#else // ^^^^ >=6.7.0 // !WIN32 <6.7.0 &QCheckBox::stateChanged, +#endif // (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)) [this]() { if (_bypassLauncher->isChecked()) { _currentEdit.bypassLauncher = _bypassLauncher->isChecked(); @@ -313,7 +326,11 @@ void SettingsDialog::createWidgets() { ); connect( _mrf.isEnabled, +#if (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)) + &QCheckBox::checkStateChanged, +#else // ^^^^ >=6.7.0 // !WIN32 <6.7.0 &QCheckBox::stateChanged, +#endif // (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)) [this]() { if (_mrf.isEnabled->isChecked()) { _currentEdit.mrf.isEnabled = _mrf.isEnabled->isChecked(); diff --git a/apps/OpenSpace/ext/launcher/src/sgctedit/displaywindowunion.cpp b/apps/OpenSpace/ext/launcher/src/sgctedit/displaywindowunion.cpp index 62ea7a1c09..6981cdd60a 100644 --- a/apps/OpenSpace/ext/launcher/src/sgctedit/displaywindowunion.cpp +++ b/apps/OpenSpace/ext/launcher/src/sgctedit/displaywindowunion.cpp @@ -194,7 +194,11 @@ void DisplayWindowUnion::initialize(const std::vector& monitorSizeList, }, [&](const sgct::config::FisheyeProjection& p) { if (p.quality.has_value()) { - wCtrl->setProjectionFisheye(*p.quality); + wCtrl->setProjectionFisheye( + *p.quality, + p.tilt.value_or(0.f), + p.fov.value_or(180.0) + ); } }, [&](const sgct::config::PlanarProjection& p) { @@ -208,7 +212,12 @@ void DisplayWindowUnion::initialize(const std::vector& monitorSizeList, wCtrl->setProjectionSphericalMirror(*p.quality); } }, - [&](const sgct::config::NoProjection&) {}, + [&](const sgct::config::NoProjection&) { + // We can only generate blitting when there is no projection selected. + if (w.blitWindowId.has_value()) { + wCtrl->setProjectionBlit(*w.blitWindowId); + } + }, [&](const sgct::config::ProjectionPlane&) {}, [&](const sgct::config::CubemapProjection&) {}, }, @@ -251,6 +260,7 @@ void DisplayWindowUnion::updateWindows() { _addWindowButton->setEnabled(_nWindowsDisplayed != _windowControls.size()); for (WindowControl* w : _windowControls) { w->showWindowLabel(_nWindowsDisplayed > 1); + w->updateWindowCount(_nWindowsDisplayed); } emit nWindowsChanged(_nWindowsDisplayed); diff --git a/apps/OpenSpace/ext/launcher/src/sgctedit/monitorbox.cpp b/apps/OpenSpace/ext/launcher/src/sgctedit/monitorbox.cpp index f21e1b1624..e5f0af53fc 100644 --- a/apps/OpenSpace/ext/launcher/src/sgctedit/monitorbox.cpp +++ b/apps/OpenSpace/ext/launcher/src/sgctedit/monitorbox.cpp @@ -32,7 +32,7 @@ MonitorBox::MonitorBox(QRect widgetSize, const std::vector& monitorResolu QWidget* parent) : QWidget(parent) { - constexpr float MarginFractionWidgetSize = 0.05f; + constexpr float MarginFractionWidgetSize = 0.02f; // // Calculate the collective size of the monitors @@ -132,7 +132,7 @@ void MonitorBox::paintEvent(QPaintEvent*) { _monitorDimensionsScaled[i].top() + 24.0 ); QFont f = QFont("Arial"); - f.setPixelSize(24); + f.setPixelSize(18); painter.setFont(f); painter.drawText(textPos, "Primary"); } @@ -148,6 +148,9 @@ void MonitorBox::paintEvent(QPaintEvent*) { std::clamp(x, 0.0, static_cast(size().width()) - 10.0), std::clamp(y, 20.0, static_cast(size().height())) ); + QFont f = QFont("Arial"); + f.setPixelSize(18); + painter.setFont(f); painter.drawText(p, QString::number(i + 1)); } diff --git a/apps/OpenSpace/ext/launcher/src/sgctedit/sgctedit.cpp b/apps/OpenSpace/ext/launcher/src/sgctedit/sgctedit.cpp index 58a9e36836..733dc087b6 100644 --- a/apps/OpenSpace/ext/launcher/src/sgctedit/sgctedit.cpp +++ b/apps/OpenSpace/ext/launcher/src/sgctedit/sgctedit.cpp @@ -68,6 +68,19 @@ namespace { return false; } + bool hasMultipleGuiWindows(const sgct::config::Cluster& cluster) { + bool foundGui = false; + for (const sgct::config::Window& window : cluster.nodes.front().windows) { + if (window.draw2D) { + if (foundGui) { + return true; + } + foundGui = true; + } + } + return false; + } + std::vector createMonitorInfoSet() { std::vector monitorSizes; for (QScreen* screen : qApp->screens()) { @@ -103,7 +116,7 @@ SgctEdit::SgctEdit(sgct::config::Cluster cluster, std::string configName, // // Monitor widget at the top of the window { - constexpr QRect MonitorWidgetSize = QRect(0, 0, 500, 500); + constexpr QRect MonitorWidgetSize = QRect(0, 0, 350, 350); MonitorBox* monitorBox = new MonitorBox(MonitorWidgetSize, monitorSizes); layout->addWidget(monitorBox, 0, Qt::AlignCenter); @@ -131,6 +144,7 @@ SgctEdit::SgctEdit(sgct::config::Cluster cluster, std::string configName, layout->addWidget(settingsContainer); QBoxLayout* settingsLayout = new QVBoxLayout(settingsContainer); settingsLayout->setContentsMargins(0, 0, 0, 0); + settingsLayout->setSpacing(0); // @@ -149,9 +163,6 @@ SgctEdit::SgctEdit(sgct::config::Cluster cluster, std::string configName, // // Orientation specification - QLabel* labelOrientation = new QLabel("Orientation"); - settingsLayout->addWidget(labelOrientation); - QWidget* orientationContainer = new QWidget; settingsLayout->addWidget(orientationContainer); QGridLayout* layoutWindow = new QGridLayout(orientationContainer); @@ -177,9 +188,6 @@ SgctEdit::SgctEdit(sgct::config::Cluster cluster, std::string configName, validatorPitch->setNotation(QDoubleValidator::StandardNotation); _linePitch->setValidator(validatorPitch); layoutWindow->addWidget(_linePitch, 0, 1); - - QLabel* range = new QLabel("Range [-90, 90] in degrees"); - layoutWindow->addWidget(range, 0, 2); } { const QString rollTip = "Roll or bank: negative numbers rotate the camera " @@ -188,7 +196,7 @@ SgctEdit::SgctEdit(sgct::config::Cluster cluster, std::string configName, QLabel* labelRoll = new QLabel("Roll"); labelRoll->setToolTip(rollTip); - layoutWindow->addWidget(labelRoll, 1, 0); + layoutWindow->addWidget(labelRoll, 0, 2); _lineRoll = new QLineEdit; _lineRoll->setText(QString::number(glm::degrees(glm::roll(q)))); @@ -196,10 +204,7 @@ SgctEdit::SgctEdit(sgct::config::Cluster cluster, std::string configName, QDoubleValidator* validatorRoll = new QDoubleValidator(-360.0, 360.0, 15); validatorRoll->setNotation(QDoubleValidator::StandardNotation); _lineRoll->setValidator(validatorRoll); - layoutWindow->addWidget(_lineRoll, 1, 1); - - QLabel* range = new QLabel("Range [-360, 360] in degrees"); - layoutWindow->addWidget(range, 1, 2); + layoutWindow->addWidget(_lineRoll, 0, 3); } { const QString yawTip = "Yaw, heading, or azimuth: negative numbers pan the " @@ -209,7 +214,7 @@ SgctEdit::SgctEdit(sgct::config::Cluster cluster, std::string configName, QLabel* labelYaw = new QLabel; labelYaw->setText("Yaw"); labelYaw->setToolTip(yawTip); - layoutWindow->addWidget(labelYaw, 2, 0); + layoutWindow->addWidget(labelYaw, 0, 4); _lineYaw = new QLineEdit; _lineYaw->setText(QString::number(glm::degrees(glm::yaw(q)))); @@ -217,10 +222,15 @@ SgctEdit::SgctEdit(sgct::config::Cluster cluster, std::string configName, QDoubleValidator* validatorYaw = new QDoubleValidator(-180.0, 180.0, 15, this); validatorYaw->setNotation(QDoubleValidator::StandardNotation); _lineYaw->setValidator(validatorYaw); - layoutWindow->addWidget(_lineYaw, 2, 1); + layoutWindow->addWidget(_lineYaw, 0, 5); + } - QLabel* range = new QLabel("Range [-180, 180] in degrees"); - layoutWindow->addWidget(range, 2, 2); + { + QLabel* info = new QLabel( + "The allowed ranges for pitch is [-90, 90], for roll [-180, 180], and for " + "yaw [-360, 360]." + ); + layoutWindow->addWidget(info, 1, 0, 1, 6); } @@ -320,6 +330,21 @@ void SgctEdit::saveCluster() { } } + if (hasMultipleGuiWindows(_cluster)) { + const int ret = QMessageBox::warning( + this, + "Multiple Windows with GUI Rendering", + "Multiple windows have 2D/GUI rendering enabled. Note that the interactable " + "user interface will only be shows on the first window with such a setting " + "if you proceed. Dashboards and other 2D elements will be shown on all " + "windows.\n\nAre you sure you want to continue?", + QMessageBox::StandardButtons(QMessageBox::Yes | QMessageBox::No) + ); + if (ret == QMessageBox::No) { + return; + } + } + if (_configurationFilename.empty()) { const QString fileName = QFileDialog::getSaveFileName( this, diff --git a/apps/OpenSpace/ext/launcher/src/sgctedit/windowcontrol.cpp b/apps/OpenSpace/ext/launcher/src/sgctedit/windowcontrol.cpp index 96fa09ded0..de4c3a18e8 100644 --- a/apps/OpenSpace/ext/launcher/src/sgctedit/windowcontrol.cpp +++ b/apps/OpenSpace/ext/launcher/src/sgctedit/windowcontrol.cpp @@ -64,7 +64,8 @@ namespace { Fisheye, SphericalMirror, Cylindrical, - Equirectangular + Equirectangular, + Blit }; constexpr int LineEditWidthFixedWindowSize = 95; @@ -161,7 +162,7 @@ WindowControl::WindowControl(int monitorIndex, int windowIndex, _windowName = new QLineEdit; _windowName->setToolTip(tip); - layout->addWidget(_windowName, 1, 1, 1, 7); + layout->addWidget(_windowName, 1, 1, 1, 3); } const QString tip = "The monitor where this window is located"; @@ -187,9 +188,9 @@ WindowControl::WindowControl(int monitorIndex, int windowIndex, // potential nullpointer accesses elsewhere in the code QLabel* labelLocation = new QLabel("Monitor"); labelLocation->setToolTip(tip); - layout->addWidget(labelLocation, 2, 0); + layout->addWidget(labelLocation, 1, 4); - layout->addWidget(_monitor, 2, 1, 1, 7); + layout->addWidget(_monitor, 1, 5, 1, 4); } // @@ -378,7 +379,7 @@ WindowControl::WindowControl(int monitorIndex, int windowIndex, _projectionType = new QComboBox; _projectionType->addItems({ "Planar Projection", "Fisheye", "Spherical Mirror Projection", - "Cylindrical Projection", "Equirectangular Projection" + "Cylindrical Projection", "Equirectangular Projection", "Copy Window Contents" }); _projectionType->setToolTip("Select from the supported window projection types"); _projectionType->setCurrentIndex(0); @@ -403,6 +404,9 @@ WindowControl::WindowControl(int monitorIndex, int windowIndex, _equirectangular.widget = createEquirectangularWidget(); projectionLayout->addWidget(_equirectangular.widget); + _blit.widget = createBlitWidget(); + projectionLayout->addWidget(_blit.widget); + // We need to trigger this once to ensure that all of the defaults are correct onProjectionChanged(0); @@ -424,21 +428,21 @@ QWidget* WindowControl::createPlanarWidget() { QGridLayout* layout = new QGridLayout(widget); layout->setColumnStretch(1, 1); - _planar.labelInfo = new QLabel( + QLabel* labelInfo = new QLabel( "This projection type is the 'regular' projection with a horizontal and a " "vertical field of view, given in degrees. The wider the field of view, the " "more content is shown at the same time, but everything becomes smaller. Very " "large values will introduce distortions on the corners." ); - _planar.labelInfo->setObjectName("info"); - _planar.labelInfo->setWordWrap(true); - layout->addWidget(_planar.labelInfo, 0, 0, 1, 3); + labelInfo->setObjectName("info"); + labelInfo->setWordWrap(true); + layout->addWidget(labelInfo, 0, 0, 1, 3); - _planar.labelFovH = new QLabel("Horizontal FOV"); + QLabel* labelFovH = new QLabel("Horizontal FOV"); const QString hfovTip = "The total horizontal field of view of the viewport (degrees)"; - _planar.labelFovH->setToolTip(hfovTip); - layout->addWidget(_planar.labelFovH, 1, 0); + labelFovH->setToolTip(hfovTip); + layout->addWidget(labelFovH, 1, 0); _planar.fovH = new QDoubleSpinBox; _planar.fovH->setMinimum(FovEpsilon); @@ -452,11 +456,11 @@ QWidget* WindowControl::createPlanarWidget() { ); layout->addWidget(_planar.fovH, 1, 1); - _planar.labelFovV = new QLabel("Vertical FOV"); + QLabel* labelFovV = new QLabel("Vertical FOV"); const QString vfovTip = "The total vertical field of view of the viewport (degrees). " "Internally,\nthe values for 'up' & 'down' will each be half this value"; - _planar.labelFovV->setToolTip(vfovTip); - layout->addWidget(_planar.labelFovV, 2, 0); + labelFovV->setToolTip(vfovTip); + layout->addWidget(labelFovV, 2, 0); _planar.fovV = new QDoubleSpinBox; _planar.fovV->setMinimum(FovEpsilon); @@ -493,29 +497,30 @@ QWidget* WindowControl::createFisheyeWidget() { // *------------*-----------* // | { Informational text } | Row 0 // | Quality * [DDDDD>] | Row 1 - // | [] Spout Output | Row 2 + // | Tilt * [oooooo] | Row 2 + // | FOV * [oooooo] | Row 3 // *------------*-----------* QWidget* widget = new QWidget; QGridLayout* layout = new QGridLayout(widget); layout->setColumnStretch(1, 1); - _fisheye.labelInfo = new QLabel( + QLabel* labelInfo = new QLabel( "This projection provides a rendering in a format that is suitable for " "planetariums and other immersive environments. A field-of-view of 180 degrees " "is presented as a circular image in the center of the screen. For this " "projection a square window is suggested, but not necessary." ); - _fisheye.labelInfo->setObjectName("info"); - _fisheye.labelInfo->setWordWrap(true); - layout->addWidget(_fisheye.labelInfo, 0, 0, 1, 2); + labelInfo->setObjectName("info"); + labelInfo->setWordWrap(true); + layout->addWidget(labelInfo, 0, 0, 1, 2); - _fisheye.labelQuality = new QLabel("Quality"); + QLabel* labelQuality = new QLabel("Quality"); const QString qualityTip = "Determines the pixel resolution of the projection " "rendering. The higher resolution,\nthe better the rendering quality, but at the " - "expense of increased rendering times"; - _fisheye.labelQuality->setToolTip(qualityTip); - layout->addWidget(_fisheye.labelQuality, 1, 0); + "expense of increased rendering times."; + labelQuality->setToolTip(qualityTip); + layout->addWidget(labelQuality, 1, 0); _fisheye.quality = new QComboBox; _fisheye.quality->addItems(qualityList()); @@ -523,6 +528,31 @@ QWidget* WindowControl::createFisheyeWidget() { _fisheye.quality->setCurrentIndex(2); layout->addWidget(_fisheye.quality, 1, 1); + QLabel* labelTilt = new QLabel("Tilt"); + const QString tiltTip = "Determines the tilt (in degrees) of the fisheye rendering. " + "Changing this value will cause the entire rendering to be tilted by the set " + "number of degrees."; + labelTilt->setToolTip(tiltTip); + layout->addWidget(labelTilt, 2, 0); + + _fisheye.tilt = new QDoubleSpinBox; + _fisheye.tilt->setToolTip(tiltTip); + _fisheye.tilt->setMinimum(-180.0); + _fisheye.tilt->setMaximum(180.0); + layout->addWidget(_fisheye.tilt, 2, 1); + + QLabel* labelFov = new QLabel("FOV"); + const QString fovTip = "Set the fisheye/dome field-of-view angle used in the fisheye " + "renderer."; + labelFov->setToolTip(fovTip); + layout->addWidget(labelFov, 3, 0); + + _fisheye.fov = new QDoubleSpinBox; + _fisheye.fov->setToolTip(fovTip); + _fisheye.fov->setMinimum(0.0); + _fisheye.fov->setMaximum(360.0); + layout->addWidget(_fisheye.fov, 3, 1); + return widget; } @@ -536,22 +566,22 @@ QWidget* WindowControl::createSphericalMirrorWidget() { QGridLayout* layout = new QGridLayout(widget); layout->setColumnStretch(1, 1); - _sphericalMirror.labelInfo = new QLabel( + QLabel* labelInfo = new QLabel( "This projection is rendering a image suite for use with a spherical mirror " "projection as described by Paul Bourke (http://paulbourke.net/dome/mirrordome/) " "and which is a low-cost yet effective way to provide content for a sphericalal " "display surface using a regular projector." ); - _sphericalMirror.labelInfo->setObjectName("info"); - _sphericalMirror.labelInfo->setWordWrap(true); - layout->addWidget(_sphericalMirror.labelInfo, 0, 0, 1, 2); + labelInfo->setObjectName("info"); + labelInfo->setWordWrap(true); + layout->addWidget(labelInfo, 0, 0, 1, 2); - _sphericalMirror.labelQuality = new QLabel("Quality"); + QLabel* labelQuality = new QLabel("Quality"); const QString qualityTip = "Determines the pixel resolution of the projection " "rendering. The higher resolution,\nthe better the rendering quality, but at the " "expense of increased rendering times"; - _sphericalMirror.labelQuality->setToolTip(qualityTip); - layout->addWidget(_sphericalMirror.labelQuality, 1, 0); + labelQuality->setToolTip(qualityTip); + layout->addWidget(labelQuality, 1, 0); _sphericalMirror.quality = new QComboBox; _sphericalMirror.quality->addItems(qualityList()); @@ -573,22 +603,22 @@ QWidget* WindowControl::createCylindricalWidget() { QGridLayout* layout = new QGridLayout(widget); layout->setColumnStretch(1, 1); - _cylindrical.labelInfo = new QLabel( + QLabel* labelInfo = new QLabel( "This projection type provides a cylindrical rendering that covers 360 degrees " "around the camera, which can be useful in immersive environments that are not " "spherical, but where, for example, all walls of a room are covered with " "projectors." ); - _cylindrical.labelInfo->setObjectName("info"); - _cylindrical.labelInfo->setWordWrap(true); - layout->addWidget(_cylindrical.labelInfo, 0, 0, 1, 2); + labelInfo->setObjectName("info"); + labelInfo->setWordWrap(true); + layout->addWidget(labelInfo, 0, 0, 1, 2); - _cylindrical.labelQuality = new QLabel("Quality"); + QLabel* labelQuality = new QLabel("Quality"); const QString qualityTip = "Determines the pixel resolution of the projection " "rendering. The higher resolution,\nthe better the rendering quality, but at the " "expense of increased rendering times"; - _cylindrical.labelQuality->setToolTip(qualityTip); - layout->addWidget(_cylindrical.labelQuality, 1, 0); + labelQuality->setToolTip(qualityTip); + layout->addWidget(labelQuality, 1, 0); _cylindrical.quality = new QComboBox; _cylindrical.quality->addItems(qualityList()); @@ -596,13 +626,13 @@ QWidget* WindowControl::createCylindricalWidget() { _cylindrical.quality->setCurrentIndex(2); layout->addWidget(_cylindrical.quality, 1, 1); - _cylindrical.labelHeightOffset = new QLabel("Height Offset"); + QLabel* labelHeightOffset = new QLabel("Height Offset"); const QString heightTip = "Offsets the height from which the cylindrical projection " "is generated.\nThis is, in general, only necessary if the user position is " "offset and\ncountering that offset is desired in order to continue producing\n" "a 'standard' cylindrical projection"; - _cylindrical.labelHeightOffset->setToolTip(heightTip); - layout->addWidget(_cylindrical.labelHeightOffset, 2, 0); + labelHeightOffset->setToolTip(heightTip); + layout->addWidget(labelHeightOffset, 2, 0); _cylindrical.heightOffset = new QDoubleSpinBox; _cylindrical.heightOffset->setMinimum(-1000000.0); @@ -611,7 +641,6 @@ QWidget* WindowControl::createCylindricalWidget() { _cylindrical.heightOffset->setToolTip(heightTip); layout->addWidget(_cylindrical.heightOffset, 2, 1); - return widget; } @@ -620,28 +649,27 @@ QWidget* WindowControl::createEquirectangularWidget() { // *------------*-----------* // | { Informational text } | Row 0 // | Quality * [DDDDD>] | Row 1 - // | [] Spout Output | Row 2 // *------------*-----------* QWidget* widget = new QWidget; QGridLayout* layout = new QGridLayout(widget); layout->setColumnStretch(1, 1); - _equirectangular.labelInfo = new QLabel( + QLabel* labelInfo = new QLabel( "This projection provides the rendering as an image in equirectangular " "projection, which is a common display type for 360 surround video. When " "uploading a video in equirectangular projection to YouTube, for example, it " "will use it as a 360 video." ); - _equirectangular.labelInfo->setObjectName("info"); - _equirectangular.labelInfo->setWordWrap(true); - layout->addWidget(_equirectangular.labelInfo, 0, 0, 1, 2); + labelInfo->setObjectName("info"); + labelInfo->setWordWrap(true); + layout->addWidget(labelInfo, 0, 0, 1, 2); - _equirectangular.labelQuality = new QLabel("Quality"); + QLabel* labelQuality = new QLabel("Quality"); const QString qualityTip = "Determines the pixel resolution of the projection " "rendering. The higher resolution,\nthe better the rendering quality, but at the " "expense of increased rendering times"; - _equirectangular.labelQuality->setToolTip(qualityTip); - layout->addWidget(_equirectangular.labelQuality, 1, 0); + labelQuality->setToolTip(qualityTip); + layout->addWidget(labelQuality, 1, 0); _equirectangular.quality = new QComboBox; _equirectangular.quality->addItems(qualityList()); @@ -652,6 +680,49 @@ QWidget* WindowControl::createEquirectangularWidget() { return widget; } +QWidget* WindowControl::createBlitWidget() { + // Column 0 Column 1 + // *------------*-----------* + // | { Informational text } | Row 0 + // | Window ID * [DDDDD>] | Row 1 + // | { Unavailability } | Row 2 + // *------------*-----------* + + QWidget* widget = new QWidget; + QGridLayout* layout = new QGridLayout(widget); + layout->setColumnStretch(1, 1); + + QLabel* labelInfo = new QLabel( + "This projection type will reuse the contents of another window. This can be " + "useful for GUI windows that should show the 3D scene, but not incur the cost of " + "rendering the scene twice. Note that the contents of the rendering will be " + "copied in their entirety, which means that if the rendering windows have " + "different aspect ratios, the image in the receiving window will be stretched." + ); + labelInfo->setObjectName("info"); + labelInfo->setWordWrap(true); + layout->addWidget(labelInfo, 0, 0, 1, 2); + + QLabel* labelBlitId = new QLabel("Window ID"); + const QString blitTip = "Determines the window from which to copy the contents."; + labelBlitId->setToolTip(blitTip); + layout->addWidget(labelBlitId, 1, 0); + + _blit.windowId = new QComboBox; + _blit.windowId->setToolTip(blitTip); + layout->addWidget(_blit.windowId, 1, 1); + + _blit.unavailable = new QLabel( + "It is only possible to copy the contents of another window if at least two " + "windows have been created. Add a second window before selecting this projection " + "type." + ); + _blit.unavailable->setWordWrap(true); + layout->addWidget(_blit.unavailable, 2, 0, 1, 2); + + return widget; +} + void WindowControl::resetToDefaults() { // // Determine ideal window sizes @@ -684,9 +755,12 @@ void WindowControl::resetToDefaults() { _planar.fovV->setValue(DefaultFovShortEdge); _cylindrical.heightOffset->setValue(DefaultHeightOffset); _fisheye.quality->setCurrentIndex(2); + _fisheye.tilt->setValue(0.0); + _fisheye.fov->setValue(180.0); _sphericalMirror.quality->setCurrentIndex(2); _cylindrical.quality->setCurrentIndex(2); _equirectangular.quality->setCurrentIndex(2); + _blit.windowId->setCurrentIndex(0); emit windowChanged(_monitorIndexDefault, _windowIndex, _windowDimensions); } @@ -736,6 +810,7 @@ void WindowControl::generateWindowInformation(sgct::config::Window& window) cons ); window.draw2D = _render2D->isChecked(); window.draw3D = _render3D->isChecked(); + window.isDecorated = _windowDecoration->isChecked(); if (_spoutOutput->isChecked()) { window.spout = sgct::config::Window::Spout{ @@ -746,6 +821,8 @@ void WindowControl::generateWindowInformation(sgct::config::Window& window) cons window.name = _windowName->text().toStdString(); } + window.viewports.clear(); + // The rest of this function is just specifying the rendering, which we can skip if we // don't want to render 3D anyway if (!window.draw3D) { @@ -760,9 +837,9 @@ void WindowControl::generateWindowInformation(sgct::config::Window& window) cons switch (static_cast(_projectionType->currentIndex())) { case ProjectionIndices::Fisheye: vp.projection = sgct::config::FisheyeProjection { - .fov = 180.f, + .fov = static_cast(_fisheye.fov->value()), .quality = Quality[_fisheye.quality->currentIndex()].first, - .tilt = 0.f + .tilt = static_cast(_fisheye.tilt->value()), }; break; case ProjectionIndices::SphericalMirror: @@ -781,6 +858,16 @@ void WindowControl::generateWindowInformation(sgct::config::Window& window) cons .quality = Quality[_equirectangular.quality->currentIndex()].first }; break; + case ProjectionIndices::Blit: + // We have to subtract here as SGCT uses 0-indexing, but we present it to the + // user as 1-indexing + window.blitWindowId = _blit.windowId->currentText().toInt() - 1; + window.draw3D = false; + + // We are falling through the planar value on purpose as for a variety of + // reasons requires a projection to be defined even when we are blitting the + // contents of another window. + [[fallthrough]]; case ProjectionIndices::Planar: { double fovH = _planar.fovH->value(); @@ -799,8 +886,6 @@ void WindowControl::generateWindowInformation(sgct::config::Window& window) cons break; } } - - window.viewports.clear(); window.viewports.push_back(vp); } @@ -810,8 +895,10 @@ void WindowControl::setProjectionPlanar(float hfov, float vfov) { _projectionType->setCurrentIndex(static_cast(ProjectionIndices::Planar)); } -void WindowControl::setProjectionFisheye(int quality) { +void WindowControl::setProjectionFisheye(int quality, float tilt, float fov) { _fisheye.quality->setCurrentIndex(indexForQuality(quality)); + _fisheye.tilt->setValue(tilt); + _fisheye.fov->setValue(fov); _projectionType->setCurrentIndex(static_cast(ProjectionIndices::Fisheye)); } @@ -835,6 +922,32 @@ void WindowControl::setProjectionEquirectangular(int quality) { ); } +void WindowControl::setProjectionBlit(int windowBlitId) { + // We add 1 here as SGCT uses a 0-indexing for the window idx, but we present it to + // the user as a 1-indexing + int idx = _blit.windowId->findText(QString::number(windowBlitId + 1)); + ghoul_assert(idx != -1, "Could not find window blit id"); + _blit.windowId->setCurrentIndex(idx); + _projectionType->setCurrentIndex( + static_cast(ProjectionIndices::Blit) + ); +} + +void WindowControl::updateWindowCount(int newWindowCount) { + QString currentIdx = _blit.windowId->currentText(); + _blit.windowId->clear(); + for (int idx = 0; idx < newWindowCount; idx++) { + if (idx == _windowIndex) { + continue; + } + _blit.windowId->addItem(QString::number(idx + 1)); + } + _blit.windowId->setCurrentText(currentIdx); + + // Set the correct visibility + _blit.unavailable->setVisible(newWindowCount == 1); +} + void WindowControl::onSizeXChanged(int newValue) { _windowDimensions.setWidth(newValue); if (_aspectRatioLocked) { @@ -896,6 +1009,7 @@ void WindowControl::onProjectionChanged(int newSelection) const { _sphericalMirror.widget->setVisible(selected == ProjectionIndices::SphericalMirror); _cylindrical.widget->setVisible(selected == ProjectionIndices::Cylindrical); _equirectangular.widget->setVisible(selected == ProjectionIndices::Equirectangular); + _blit.widget->setVisible(selected == ProjectionIndices::Blit); } void WindowControl::onAspectRatioLockClicked() { diff --git a/apps/OpenSpace/ext/launcher/src/splitcombobox.cpp b/apps/OpenSpace/ext/launcher/src/splitcombobox.cpp index ee8ffd0be7..c97e2b2f36 100644 --- a/apps/OpenSpace/ext/launcher/src/splitcombobox.cpp +++ b/apps/OpenSpace/ext/launcher/src/splitcombobox.cpp @@ -24,8 +24,10 @@ #include "splitcombobox.h" +#include "usericon.h" #include #include +#include #include SplitComboBox::SplitComboBox(QWidget* parent, std::filesystem::path userPath, @@ -42,6 +44,8 @@ SplitComboBox::SplitComboBox(QWidget* parent, std::filesystem::path userPath, , _fileFilter(std::move(fileFilter)) , _createTooltip(std::move(createTooltip)) { + setCursor(Qt::PointingHandCursor); + connect( this, QOverload::of(&QComboBox::currentIndexChanged), @@ -66,14 +70,25 @@ void SplitComboBox::populateList(const std::string& preset) { // Clear the previously existing entries since we might call this function again clear(); + // Create "icons" that we use to indicate whether an item is built-in or user content + QIcon icon = userIcon(); // // Special item (if it was specified) if (!_specialFirst.empty()) { - addItem( - QString::fromStdString(_specialFirst), - QString::fromStdString(_specialFirst) - ); + if (_specialFirst.starts_with(_userPath.string())) { + addItem( + icon, + QString::fromStdString(_specialFirst), + QString::fromStdString(_specialFirst) + ); + } + else { + addItem( + QString::fromStdString(_specialFirst), + QString::fromStdString(_specialFirst) + ); + } } @@ -94,6 +109,7 @@ void SplitComboBox::populateList(const std::string& preset) { // Display the relative path, but store the full path in the user data segment addItem( + icon, QString::fromStdString(relPath.string()), QString::fromStdString(p.string()) ); diff --git a/apps/OpenSpace/ext/launcher/src/usericon.cpp b/apps/OpenSpace/ext/launcher/src/usericon.cpp new file mode 100644 index 0000000000..2374c39e4a --- /dev/null +++ b/apps/OpenSpace/ext/launcher/src/usericon.cpp @@ -0,0 +1,43 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2025 * + * * + * 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 "usericon.h" + +#include + +QIcon userIcon() { + QPixmap px = QPixmap(40, 50); + px.fill(Qt::transparent); + + QPainter painter = QPainter(&px); + painter.setBrush(QColor(183, 211, 149, 255)); + painter.drawEllipse(0, 10, 38, 38); + + QFont f = QFont("Arial"); + f.setPixelSize(28); + f.setBold(true); + painter.setFont(f); + painter.drawText(0, 10, 40, 40, Qt::AlignCenter, "U"); + return QIcon(px); +} diff --git a/apps/OpenSpace/ext/sgct b/apps/OpenSpace/ext/sgct index 0afa47198a..020c3b2a90 160000 --- a/apps/OpenSpace/ext/sgct +++ b/apps/OpenSpace/ext/sgct @@ -1 +1 @@ -Subproject commit 0afa47198a395a528b54aa2bbc827ddd23927afe +Subproject commit 020c3b2a90eb492fc80e7d9eb445825b83dca71b diff --git a/apps/OpenSpace/main.cpp b/apps/OpenSpace/main.cpp index c03c43f681..cd5aa8a720 100644 --- a/apps/OpenSpace/main.cpp +++ b/apps/OpenSpace/main.cpp @@ -29,6 +29,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -37,7 +40,9 @@ #include #include #include +#include #include +#include #include #ifdef WIN32 #define GLFW_EXPOSE_NATIVE_WIN32 @@ -78,6 +83,18 @@ #include #include +#ifdef WIN32 +extern "C" { + // These variables are checked by the different drivers to see if the discrete GPU + // should be preferred + + // Nvidia Optimus: force switch to discrete GPU + __declspec(dllexport) DWORD NvOptimusEnablement = 1; + // AMD + __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; +} // extern +#endif // WIN32 + using namespace openspace; using namespace sgct; @@ -98,6 +115,11 @@ glm::ivec2 currentDrawResolution; Window* FirstOpenVRWindow = nullptr; #endif +// This value is specified from the commandline options and kept around to be run after +// everything has been initialized. It's going to be std::nullopt unless a user wants to +// run a task +std::optional taskToRun; + // // SPOUT-support // @@ -399,6 +421,40 @@ void mainInitFunc(GLFWwindow*) { // Query joystick status, those connected before start up checkJoystickStatus(); + if (taskToRun.has_value()) { + // If a task was specified on the commandline line, we are loading that file and + // executing everything within + + TaskLoader loader; + std::vector> tasks = loader.tasksFromFile(*taskToRun); + + size_t nTasks = tasks.size(); + if (nTasks == 1) { + LINFO("Task queue has 1 item"); + } + else { + LINFO(std::format("Task queue has {} items", tasks.size())); + } + + for (size_t i = 0; i < tasks.size(); i++) { + Task& task = *tasks[i].get(); + LINFO(std::format( + "Performing task {} out of {}: {}", + i + 1, tasks.size(), task.description() + )); + ProgressBar progressBar = ProgressBar(100); + auto onProgress = [&progressBar](float progress) { + progressBar.print(static_cast(progress * 100.f)); + }; + task.perform(onProgress); + } + std::cout << "Done performing tasks" << std::endl; + + // Done with the tasks, so we can terminate + Engine::instance().terminate(); + } + + LTRACE("main::mainInitFunc(end)"); } @@ -703,6 +759,16 @@ void setSgctDelegateFunctions() { return currentWindow->isWindowResized(); }; + sgctDelegate.anyWindowHasResized = []() { + ZoneScoped; + + for (const std::unique_ptr& window : Engine::instance().windows()) { + if (window->isWindowResized()) { + return true; + } + } + return false; + }; sgctDelegate.averageDeltaTime = []() { ZoneScoped; @@ -923,24 +989,40 @@ void setSgctDelegateFunctions() { return Engine::instance().windows().front()->id(); }; + sgctDelegate.nameForWindow = [](int windowIdx) { + ZoneScoped; + + ghoul_assert( + windowIdx >= 0 && + windowIdx < Engine::instance().windows().size(), + "Invalid window index" + ); + return Engine::instance().windows()[windowIdx]->name(); + }; sgctDelegate.openGLProcedureAddress = [](const char* func) { ZoneScoped; return glfwGetProcAddress(func); }; - sgctDelegate.getHorizFieldOfView = []() { + sgctDelegate.horizFieldOfView = [](int windowIdx) { ZoneScoped; - return static_cast( - Engine::instance().windows().front()->horizFieldOfViewDegrees() + ghoul_assert( + windowIdx >= 0 && + windowIdx < Engine::instance().windows().size(), + "Invalid window index" ); + return Engine::instance().windows()[windowIdx]->horizFieldOfViewDegrees(); }; - sgctDelegate.setHorizFieldOfView = [](float hFovDeg) { + sgctDelegate.setHorizFieldOfView = [](int windowIdx, float hFovDeg) { ZoneScoped; - for (std::unique_ptr const& w : Engine::instance().windows()) { - w->setHorizFieldOfView(hFovDeg); - } + ghoul_assert( + windowIdx >= 0 && + windowIdx < Engine::instance().windows().size(), + "Invalid window index" + ); + Engine::instance().windows()[windowIdx]->setHorizFieldOfView(hFovDeg); }; #ifdef WIN32 sgctDelegate.getNativeWindowHandle = [](size_t windowIndex) -> void* { @@ -1013,47 +1095,66 @@ void setSgctDelegateFunctions() { sgctDelegate.setStatisticsGraphScale = [](float scale) { sgct::Engine::instance().setStatsGraphScale(scale); }; + sgctDelegate.setStatisticsGraphOffset = [](glm::vec2 offset) { + sgct::Engine::instance().setStatsGraphOffset(sgct::vec2{ offset.x, offset.y }); + }; sgctDelegate.setMouseCursor = [](WindowDelegate::Cursor mouse) { + auto createGLFWCursor = [](int shape) { + GLFWerrorfun prevErrorCallback = glfwSetErrorCallback(nullptr); + defer { glfwSetErrorCallback(prevErrorCallback); }; + + GLFWcursor* cursor = glfwCreateStandardCursor(shape); + if (!cursor) { + LINFO(std::format( + "Replacing unavailable cursor shape {} with arrow cursor ({})", + shape, GLFW_ARROW_CURSOR + )); + return glfwCreateStandardCursor(GLFW_ARROW_CURSOR); + } + + return cursor; + }; + static std::unordered_map Cursors = { { WindowDelegate::Cursor::Arrow, - glfwCreateStandardCursor(GLFW_ARROW_CURSOR) + createGLFWCursor(GLFW_ARROW_CURSOR) }, { WindowDelegate::Cursor::IBeam, - glfwCreateStandardCursor(GLFW_IBEAM_CURSOR) + createGLFWCursor(GLFW_IBEAM_CURSOR) }, { WindowDelegate::Cursor::CrossHair, - glfwCreateStandardCursor(GLFW_CROSSHAIR_CURSOR) + createGLFWCursor(GLFW_CROSSHAIR_CURSOR) }, { WindowDelegate::Cursor::PointingHand, - glfwCreateStandardCursor(GLFW_POINTING_HAND_CURSOR) + createGLFWCursor(GLFW_POINTING_HAND_CURSOR) }, { WindowDelegate::Cursor::ResizeEW, - glfwCreateStandardCursor(GLFW_RESIZE_EW_CURSOR) + createGLFWCursor(GLFW_RESIZE_EW_CURSOR) }, { WindowDelegate::Cursor::ResizeNS, - glfwCreateStandardCursor(GLFW_RESIZE_NS_CURSOR) + createGLFWCursor(GLFW_RESIZE_NS_CURSOR) }, { WindowDelegate::Cursor::ResizeNWSE, - glfwCreateStandardCursor(GLFW_RESIZE_NWSE_CURSOR) + createGLFWCursor(GLFW_RESIZE_NWSE_CURSOR) }, { WindowDelegate::Cursor::ResizeNESW, - glfwCreateStandardCursor(GLFW_RESIZE_NESW_CURSOR) + createGLFWCursor(GLFW_RESIZE_NESW_CURSOR) }, { WindowDelegate::Cursor::ResizeAll, - glfwCreateStandardCursor(GLFW_RESIZE_ALL_CURSOR) + createGLFWCursor(GLFW_RESIZE_ALL_CURSOR) }, { WindowDelegate::Cursor::NotAllowed, - glfwCreateStandardCursor(GLFW_NOT_ALLOWED_CURSOR) + createGLFWCursor(GLFW_NOT_ALLOWED_CURSOR) }, }; ghoul_assert( @@ -1069,6 +1170,12 @@ void setSgctDelegateFunctions() { int main(int argc, char* argv[]) { ZoneScoped; + // For debugging purposes: Enforce Light Mode in Qt + // qputenv("QT_QPA_PLATFORM", "windows:darkmode=0"); + + // For debugging purposes: Enforce Dark Mode in Qt + // qputenv("QT_QPA_PLATFORM", "windows:darkmode=1"); + #ifdef OPENSPACE_BREAK_ON_FLOATING_POINT_EXCEPTION _clearfp(); _controlfp(_controlfp(0, 0) & ~(_EM_ZERODIVIDE | _EM_OVERFLOW), _MCW_EM); @@ -1118,41 +1225,56 @@ int main(int argc, char* argv[]) { CommandlineArguments commandlineArguments; parser.addCommand(std::make_unique>( - commandlineArguments.configuration, "--file", "-f", + commandlineArguments.configuration, + "--file", + "-f", "Provides the path to the OpenSpace configuration file. Only the '${TEMPORARY}' " "path token is available and any other path has to be specified relative to the " "current working directory" )); parser.addCommand(std::make_unique>( - commandlineArguments.windowConfig, "--config", "-c", + commandlineArguments.windowConfig, + "--config", + "-c", "Specifies the window configuration file that should be used to start OpenSpace " "and that will override whatever is specified in the `openspace.cfg` or the " "settings. This value can include path tokens, so for example " "`${CONFIG}/single.json` is a valid value." )); parser.addCommand(std::make_unique>( - commandlineArguments.profile, "--profile", "-p", + commandlineArguments.profile, + "--profile", + "-p", "Specifies the profile that should be used to start OpenSpace and that overrides " "the profile specified in the `openspace.cfg` and the settings." )); parser.addCommand(std::make_unique>( - commandlineArguments.propertyVisibility, "--propertyVisibility", "", + commandlineArguments.propertyVisibility, + "--propertyVisibility", + "", "Specifies UI visibility settings for properties that this OpenSpace is using. " "This value overrides the values specified in the `openspace.cfg` and the " "settings and also the environment variable, if that value is provided. Allowed " "values for this parameter are: `Developer`, `AdvancedUser`, `User`, and " "`NoviceUser`." )); + parser.addCommand(std::make_unique>( + commandlineArguments.task, + "--task", + "-t", + "Specifies a task that will be run after OpenSpace has been initialized. Once " + "the task finishes, the application will automatically close again. All other " + "commandline arguments are ignored, if a task is specified." + )); parser.addCommand(std::make_unique( - commandlineArguments.bypassLauncher, "--bypassLauncher", "-b", + commandlineArguments.bypassLauncher, + "--bypassLauncher", + "-b", "Specifies whether the Launcher should be shown at startup or not. This value " "overrides the value specified in the `openspace.cfg` and the settings." )); - // setCommandLine returns a reference to the vector that will be filled later - const std::vector& sgctArguments = parser.setCommandLine( - { argv, argv + argc } - ); + parser.setCommandLine({ argv, argv + argc }); try { const bool showHelp = parser.execute(); @@ -1165,8 +1287,16 @@ int main(int argc, char* argv[]) { LFATALC(e.component, e.message); exit(EXIT_FAILURE); } - // Take an actual copy of the arguments - std::vector arguments = sgctArguments; + + if (commandlineArguments.task.has_value()) { + // If a task was specified, we want to overwrite the used window and profile and + // not display the launcher + commandlineArguments.windowConfig = "${CONFIG}/single.json"; + commandlineArguments.profile = "empty"; + commandlineArguments.bypassLauncher = true; + + taskToRun = *commandlineArguments.task; + } // // Set up SGCT functions for window delegate @@ -1391,7 +1521,10 @@ int main(int argc, char* argv[]) { config = launcher.selectedWindowConfig(); if (config.find(labelFromCfgFile) != std::string::npos) { if (config.find("sgct.config") == std::string::npos) { - config = config.substr(0, config.length() - labelFromCfgFile.length()); + config = config.substr( + 0, + config.length() - labelFromCfgFile.length() + ); } else { config = windowConfiguration; @@ -1412,11 +1545,40 @@ int main(int argc, char* argv[]) { { openspace::Settings settings = loadSettings(); - settings.hasStartedBefore = true; - const std::filesystem::path p = global::configuration->profile; - const std::filesystem::path reducedName = p.filename().replace_extension(); - settings.profile = reducedName.string(); + const std::filesystem::path profile = global::configuration->profile; + + const bool isDefaultProfile = ghoul::filesystem::isSubdirectory( + profile, + absPath("${PROFILES}") + ); + const bool isUserProfile = ghoul::filesystem::isSubdirectory( + profile, + absPath("${USER_PROFILES}") + ); + + if (isDefaultProfile) { + std::filesystem::path p = std::filesystem::relative( + profile, + absPath("${PROFILES}") + ); + p.replace_extension(); + settings.profile = p.string(); + } + else if (isUserProfile) { + std::filesystem::path p = std::filesystem::relative( + profile, + absPath("${USER_PROFILES}") + ); + p.replace_extension(); + settings.profile = p.string(); + } + else { + LWARNING( + "Cannot save remembered profile when starting a profile that is not in " + "the data/profiles or user/data/profiles folder." + ); + } settings.configuration = isGeneratedWindowConfig ? "" : global::configuration->windowConfiguration; @@ -1424,17 +1586,7 @@ int main(int argc, char* argv[]) { saveSettings(settings, findSettings()); } - // Prepend the outgoing sgctArguments with the program name - // as well as the configuration file that sgct is supposed to use - arguments.insert(arguments.begin(), argv[0]); - arguments.insert(arguments.begin() + 1, "-config"); - arguments.insert( - arguments.begin() + 2, - absPath(global::configuration->windowConfiguration).string() - ); - // Need to set this before the creation of the sgct::Engine - Log::instance().setLogToConsole(false); Log::instance().setShowTime(false); Log::instance().setShowLogLevel(false); @@ -1444,9 +1596,14 @@ int main(int argc, char* argv[]) { glfwWindowHint(GLFW_STENCIL_BITS, 8); #endif + std::filesystem::path winConf = + commandlineArguments.windowConfig.has_value() ? + *commandlineArguments.windowConfig : + global::configuration->windowConfiguration; + // Determining SGCT configuration file LINFO(std::format( - "SGCT Configuration file: {}", absPath(global::configuration->windowConfiguration) + "SGCT Configuration file: {}", absPath(winConf) )); @@ -1457,9 +1614,7 @@ int main(int argc, char* argv[]) { LDEBUG("Loading cluster information"); config::Cluster cluster; try { - cluster = loadCluster( - absPath(global::configuration->windowConfiguration).string() - ); + cluster = loadCluster(absPath(winConf).string()); } catch (const std::runtime_error& e) { LFATALC("main", e.what()); diff --git a/config/single_fisheye.json b/config/single_fisheye.json index 941cf221e2..4587e961f4 100644 --- a/config/single_fisheye.json +++ b/config/single_fisheye.json @@ -19,7 +19,7 @@ "type": "FisheyeProjection", "fov": 180.0, "quality": "1k", - "tilt": 27.0, + "tilt": 90.0, "background": { "r": 0.1, "g": 0.1, "b": 0.1, "a": 1.0 } } } diff --git a/config/single_fisheye_gui.json b/config/single_fisheye_gui.json index 862ec78611..736890aa69 100644 --- a/config/single_fisheye_gui.json +++ b/config/single_fisheye_gui.json @@ -43,7 +43,7 @@ "type": "FisheyeProjection", "fov": 180.0, "quality": "1k", - "tilt": 27.0, + "tilt": 90.0, "background": { "r": 0.1, "g": 0.1, "b": 0.1, "a": 1.0 } } } diff --git a/data/assets/actions/default_actions.asset b/data/assets/actions/default_actions.asset index 6d1a891d0e..25a3ce9f8b 100644 --- a/data/assets/actions/default_actions.asset +++ b/data/assets/actions/default_actions.asset @@ -1,6 +1,312 @@ -asset.require("actions/trails/toggle_all_trails") -asset.require("actions/trails/toggle_trails_planets_moons") -asset.require("actions/planets/planet_lighting") -asset.require("actions/system/undo_event_fades") -asset.require("actions/trails/toggle_all_minor_moon_trails") -asset.require("actions/trails/on_off_all_minor_moons") +local ToggleShutdown = { + Identifier = "os.ToggleShutdown", + Name = "Toggle shutdown", + Command = "openspace.toggleShutdown()", + Documentation = [[ + Toggles the shutdown that will stop OpenSpace after a grace period. Press again to + cancel the shutdown during this period]], + GuiPath = "/System", + IsLocal = true +} + +-- Friction actions + +local ToggleRotationFriction = { + Identifier = "os.ToggleRotationFriction", + Name = "Toggle rotation friction", + Command = [[openspace.invertBooleanProperty("NavigationHandler.OrbitalNavigator.Friction.RotationalFriction")]], + Documentation = [[Toggles the rotational friction of the camera. If it is disabled, the + camera rotates around the focus object indefinitely]], + GuiPath = "/Navigation", + IsLocal = true +} + +local ToggleZoomFriction = { + Identifier = "os.ToggleZoomFriction", + Name = "Toggle zoom friction", + Command = [[openspace.invertBooleanProperty("NavigationHandler.OrbitalNavigator.Friction.ZoomFriction")]], + Documentation = [[Toggles the zoom friction of the camera. If it is disabled, the camera + rises up from or closes in towards the focus object indefinitely]], + GuiPath = "/Navigation", + IsLocal = true +} + +local ToggleRollFriction = { + Identifier = "os.ToggleRollFriction", + Name = "Toggle roll friction", + Command = [[openspace.invertBooleanProperty("NavigationHandler.OrbitalNavigator.Friction.RollFriction")]], + Documentation = [[Toggles the roll friction of the camera. If it is disabled, the camera + rolls around its own axis indefinitely]], + GuiPath = "/Navigation", + IsLocal = true +} + + +-- UI actions + +local ToggleMainGui = { + Identifier = "os.ToggleMainGui", + Name = "Toggle main GUI", + Command = [[ + openspace.invertBooleanProperty("Modules.CefWebGui.Visible") + + if not openspace.propertyValue("Modules.CefWebGui.Visible") then + local action_id = "os.ToggleMainGui" + local keys = openspace.keyBindingsForAction(action_id) + if #keys > 0 then + local key = keys[1] + openspace.printInfo( + "Hiding the user interface. You can restore it with the '" .. key .. "' key" + ) + end + end + ]], + Documentation = "Toggles the main GUI", + GuiPath = "/System/GUI", + IsLocal = true +} + +local ToggleNativeUi = { + Identifier = "os.ToggleNativeUi", + Name = "Show native GUI", + Command = [[openspace.invertBooleanProperty("Modules.ImGUI.Enabled")]], + Documentation = "Shows or hides the native UI", + GuiPath = "/System/GUI", + IsLocal = true +} + +local ReloadGui = { + Identifier = "os.ReloadGui", + Name = "Reload GUI", + Command = [[openspace.setPropertyValueSingle("Modules.CefWebGui.Reload", nil)]], + Documentation = "Reloads the GUI", + GuiPath = "/System/GUI", + IsLocal = true +} + + +-- Rendering actions + +local TakeScreenshot = { + Identifier = "os.TakeScreenshot", + Name = "Take screenshot", + Command = "openspace.takeScreenshot()", + Documentation = [[Saves the contents of the screen to a file in the ${SCREENSHOTS} + directory]], + GuiPath = "/System/Rendering", + IsLocal = true +} + +local FadeToBlack = { + Identifier = "os.FadeToBlack", + Name = "Fade to/from black", + Command = [[ + if openspace.propertyValue("RenderEngine.BlackoutFactor") > 0.5 then + openspace.setPropertyValueSingle("RenderEngine.BlackoutFactor", 0.0, 3) + else + openspace.setPropertyValueSingle("RenderEngine.BlackoutFactor", 1.0, 3) + end + ]], + Documentation = [[Toggles the fade to black within 3 seconds or shows the rendering + after 3 seconds]], + GuiPath = "/Rendering", + IsLocal = false +} + +local ToggleOverlays = { + Identifier = "os.ToggleOverlays", + Name = "Toggle dashboard and overlays", + Command = [[ + local isEnabled = openspace.propertyValue("Dashboard.IsEnabled") + openspace.setPropertyValueSingle("Dashboard.IsEnabled", not isEnabled) + openspace.setPropertyValueSingle("RenderEngine.ShowLog", not isEnabled) + openspace.setPropertyValueSingle("RenderEngine.ShowVersion", not isEnabled) + ]], + Documentation = "Toggles the dashboard and overlays", + GuiPath = "/System/GUI", + IsLocal = true +} + +local ToggleMasterRendering = { + Identifier = "os.ToggleMasterRendering", + Name = "Toggle rendering on master", + Command = [[openspace.invertBooleanProperty("RenderEngine.DisableMasterRendering")]], + Documentation = "Toggles the rendering on master", + GuiPath = "/System/Rendering", + IsLocal = true +} + + +-- Time actions + +local TogglePauseInterpolated = { + Identifier = "os.TogglePauseInterpolated", + Name = "Toggle pause (interpolate)", + Command = "openspace.time.pauseToggleViaKeyboard()", + Documentation = "Smoothly starts and stops the simulation time", + GuiPath = "/Time/Simulation Speed", + IsLocal = true +} + +local TogglePauseImmediate = { + Identifier = "os.TogglePauseImmediate", + Name = "Toggle pause (immediate)", + Command = "openspace.time.togglePause()", + Documentation = "Immediately starts and stops the simulation time", + GuiPath = "/Time/Simulation Speed", + IsLocal = true +} + +local NextDeltaStepInterpolate = { + Identifier = "os.NextDeltaStepInterpolate", + Name = "Next simulation time step (interpolate)", + Command = "openspace.time.interpolateNextDeltaTimeStep()", + Documentation = [[Smoothly interpolates the simulation speed to the next simulation time + step, if one exists]], + GuiPath = "/Time/Simulation Speed", + IsLocal = true +} + +local NextDeltaStepImmediate = { + Identifier = "os.NextDeltaStepImmediate", + Name = "Next simulation time step (immediate)", + Command = "openspace.time.setNextDeltaTimeStep()", + Documentation = [[Immediately set the simulation speed to the next simulation time step, + if one exists]], + GuiPath = "/Time/Simulation Speed", + IsLocal = true +} + +local PreviousDeltaStepInterpolate = { + Identifier = "os.PreviousDeltaStepInterpolate", + Name = "Previous simulation time step (interpolate)", + Command = "openspace.time.interpolatePreviousDeltaTimeStep()", + Documentation = [[Smoothly interpolates the simulation speed to the previous simulation + time step, if one exists]], + GuiPath = "/Time/Simulation Speed", + IsLocal = true +} + +local PreviousDeltaStepImmediate = { + Identifier = "os.PreviousDeltaStepImmediate", + Name = "Previous simulation time step (immediate)", + Command = "openspace.time.setPreviousDeltaTimeStep()", + Documentation = [[Immediately set the simulation speed to the previous simulation time + step, if one exists]], + GuiPath = "/Time/Simulation Speed", + IsLocal = true +} + +local RealTimeDeltaStepInterpolate = { + Identifier = "os.RealTimeDeltaStepInterpolate", + Name = "Reset the simulation time to realtime (interpolate)", + Command = "openspace.time.interpolateDeltaTime(1)", + Documentation = "Smoothly interpolate the simulation speed to match real-time speed", + GuiPath = "/Time/Simulation Speed", + IsLocal = true +} + +local RealTimeDeltaStepImmediate = { + Identifier = "os.RealTimeDeltaStepImmediate", + Name = "Reset the simulation time to realtime (immediate)", + Command = "openspace.time.setDeltaTime(1)", + Documentation = "Immediately set the simulation speed to match real-time speed", + GuiPath = "/Time/Simulation Speed", + IsLocal = true +} + + +asset.onInitialize(function() + openspace.action.registerAction(ToggleShutdown) + + -- Friction + openspace.action.registerAction(ToggleRotationFriction) + openspace.action.registerAction(ToggleZoomFriction) + openspace.action.registerAction(ToggleRollFriction) + + -- UI + openspace.action.registerAction(ToggleMainGui) + openspace.action.registerAction(ToggleNativeUi) + openspace.action.registerAction(ReloadGui) + + -- Rendering + openspace.action.registerAction(TakeScreenshot) + openspace.action.registerAction(FadeToBlack) + openspace.action.registerAction(ToggleOverlays) + openspace.action.registerAction(ToggleMasterRendering) + + -- Time + openspace.action.registerAction(TogglePauseInterpolated) + openspace.action.registerAction(TogglePauseImmediate) + openspace.action.registerAction(NextDeltaStepInterpolate) + openspace.action.registerAction(NextDeltaStepImmediate) + openspace.action.registerAction(PreviousDeltaStepInterpolate) + openspace.action.registerAction(PreviousDeltaStepImmediate) + openspace.action.registerAction(RealTimeDeltaStepInterpolate) + openspace.action.registerAction(RealTimeDeltaStepImmediate) +end) + +asset.onDeinitialize(function() + -- Time + openspace.action.removeAction(RealTimeDeltaStepImmediate) + openspace.action.removeAction(RealTimeDeltaStepInterpolate) + openspace.action.removeAction(PreviousDeltaStepImmediate) + openspace.action.removeAction(PreviousDeltaStepInterpolate) + openspace.action.removeAction(NextDeltaStepImmediate) + openspace.action.removeAction(NextDeltaStepInterpolate) + openspace.action.removeAction(TogglePauseImmediate) + openspace.action.removeAction(TogglePauseInterpolated) + + -- Rendering + openspace.action.removeAction(ToggleMasterRendering) + openspace.action.removeAction(ToggleOverlays) + openspace.action.removeAction(FadeToBlack) + openspace.action.removeAction(TakeScreenshot) + + -- UI + openspace.action.removeAction(ReloadGui) + openspace.action.removeAction(ToggleNativeUi) + openspace.action.removeAction(ToggleMainGui) + + -- Friction + openspace.action.removeAction(ToggleRollFriction) + openspace.action.removeAction(ToggleZoomFriction) + openspace.action.removeAction(ToggleRotationFriction) + + openspace.action.removeAction(ToggleShutdown) +end) + + +asset.export("ToggleShutdown", ToggleShutdown.Identifier) + +asset.export("ToggleRotationFriction", ToggleRotationFriction.Identifier) +asset.export("ToggleZoomFriction", ToggleZoomFriction.Identifier) +asset.export("ToggleRollFriction", ToggleRollFriction.Identifier) + +asset.export("ToggleMainGui", ToggleMainGui.Identifier) +asset.export("ToggleNativeUi", ToggleNativeUi.Identifier) +asset.export("ReloadGui", ReloadGui.Identifier) + +asset.export("TakeScreenshot", TakeScreenshot.Identifier) +asset.export("FadeToBlack", FadeToBlack.Identifier) +asset.export("ToggleOverlays", ToggleOverlays.Identifier) +asset.export("ToggleMasterRendering", ToggleMasterRendering.Identifier) + +asset.export("TogglePauseInterpolated", TogglePauseInterpolated.Identifier) +asset.export("TogglePauseImmediate", TogglePauseImmediate.Identifier) +asset.export("NextDeltaStepInterpolate", NextDeltaStepInterpolate.Identifier) +asset.export("NextDeltaStepImmediate", NextDeltaStepImmediate.Identifier) +asset.export("PreviousDeltaStepInterpolate", PreviousDeltaStepInterpolate.Identifier) +asset.export("PreviousDeltaStepImmediate", PreviousDeltaStepImmediate.Identifier) +asset.export("RealTimeDeltaStepInterpolate", RealTimeDeltaStepInterpolate.Identifier) +asset.export("RealTimeDeltaStepImmediate", RealTimeDeltaStepImmediate.Identifier) + + + +asset.meta = { + Name = "Actions - Default", + Description = "Asset providing default actions that are useful in every profile", + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/actions/nightsky/camera.asset b/data/assets/actions/nightsky/camera.asset index 7247d424f7..67cada8a00 100644 --- a/data/assets/actions/nightsky/camera.asset +++ b/data/assets/actions/nightsky/camera.asset @@ -61,7 +61,7 @@ local LookingNorth = { Command = [[ local currentNavState = openspace.navigation.getNavigationState() local newNavState = { - Pitch = math.pi / 2.0, + Pitch = math.pi, Anchor = currentNavState["Anchor"], Yaw = currentNavState["Yaw"], Position = currentNavState["Position"], @@ -74,13 +74,36 @@ local LookingNorth = { IsLocal = false } +local LookingEast = { + Identifier = "os.nightsky.LookingEast", + Name = "Looking East", + Command = [[ + local lat, lon, alt = openspace.globebrowsing.geoPositionForCamera() + local lon_rad = math.rad(lon) + local upx = -math.sin(lon_rad) + local upy = math.cos(lon_rad) + local currentNavState = openspace.navigation.getNavigationState() + local newNavState = { + Pitch = math.pi, + Anchor = currentNavState["Anchor"], + Yaw = currentNavState["Yaw"], + Position = currentNavState["Position"], + Up = { upx, upy, 0 } + } + openspace.navigation.setNavigationState(newNavState) + ]], + Documentation = "Sets the view looking up and East.", + GuiPath = "/Night Sky/View", + IsLocal = false +} + local LookingSouth = { Identifier = "os.nightsky.LookingSouth", Name = "Looking South", Command = [[ local currentNavState = openspace.navigation.getNavigationState() local newNavState = { - Pitch = math.pi / 2.0, + Pitch = math.pi, Anchor = currentNavState["Anchor"], Yaw = currentNavState["Yaw"], Position = currentNavState["Position"], @@ -88,22 +111,48 @@ local LookingSouth = { } openspace.navigation.setNavigationState(newNavState) ]], - Documentation = "Sets the view for a horizon looking South.", + Documentation = "Sets the view looking up and South.", GuiPath = "/Night Sky/View", IsLocal = false } +local LookingWest = { + Identifier = "os.nightsky.LookingWest", + Name = "Looking West", + Command = [[ + local lat, lon, alt = openspace.globebrowsing.geoPositionForCamera() + local lon_rad = math.rad(lon) + local upx = math.sin(lon_rad) + local upy = -math.cos(lon_rad) + local currentNavState = openspace.navigation.getNavigationState() + local newNavState = { + Pitch = math.pi, + Anchor = currentNavState["Anchor"], + Yaw = currentNavState["Yaw"], + Position = currentNavState["Position"], + Up = { upx, upy, 0 } + } + openspace.navigation.setNavigationState(newNavState) + ]], + Documentation = "Sets the view looking up and West.", + GuiPath = "/Night Sky/View", + IsLocal = false +} asset.onInitialize(function() openspace.action.registerAction(LookUp) openspace.action.registerAction(LevelHorizonYaw) openspace.action.registerAction(LevelHorizonPitch) openspace.action.registerAction(LookingNorth) + openspace.action.registerAction(LookingEast) openspace.action.registerAction(LookingSouth) + openspace.action.registerAction(LookingWest) end) asset.onDeinitialize(function() + openspace.action.removeAction(LookingWest) openspace.action.removeAction(LookingSouth) + openspace.action.removeAction(LookingEast) openspace.action.removeAction(LookingNorth) openspace.action.removeAction(LevelHorizonPitch) openspace.action.removeAction(LevelHorizonYaw) @@ -114,4 +163,6 @@ asset.export("LookUp", LookUp.Identifier) asset.export("LevelHorizonYaw", LevelHorizonYaw.Identifier) asset.export("LevelHorizonPitch", LevelHorizonPitch.Identifier) asset.export("LookingNorth", LookingNorth.Identifier) +asset.export("LookingEast", LookingEast.Identifier) asset.export("LookingSouth", LookingSouth.Identifier) +asset.export("LookingWest", LookingWest.Identifier) diff --git a/data/assets/actions/nightsky/createsuntrails.asset b/data/assets/actions/nightsky/createsuntrails.asset new file mode 100644 index 0000000000..8c4a70e389 --- /dev/null +++ b/data/assets/actions/nightsky/createsuntrails.asset @@ -0,0 +1,66 @@ +local AddSunTrail = { + Identifier = "os.nightsky.AddSunTrail", + Name = "Add sun trail", + Command = [[ + local date + if is_declared("args") then + if (args.Date == "NOW") then + date = openspace.time.currentWallTime() + elseif (args.Date == "UTC") then + date = openspace.time.UTC() + else + date = args.Date + end + else + date = openspace.time.UTC() + end + + local datePlus = openspace.time.advancedTime(date, '1d') + + date = string.sub(date, 1, string.find(date, "T") - 1) + datePlus = string.sub(datePlus, 1, string.find(datePlus, "T") - 1) + + local SunTrailEarth = { + Identifier = "SunTrailEarth" .. date, + Parent = "Earth", + Renderable = { + Type = "RenderableTrailTrajectory", + Translation = { + Type = "SpiceTranslation", + Target = "SUN", + Observer = "EARTH", + Frame = "IAU_EARTH", + }, + EnableFade = false, + StartTime = date, + EndTime = datePlus, + SampleInterval = 1000, + ShowFullTrail = true, + Color = { 0.9, 1.0, 0.0 }, + }, + Tag = { "sun_trail" }, + GUI = { + Name = "Sun Trail " .. date, + Path = "/Night Sky/Sun Trails", + } + } + + openspace.addSceneGraphNode(SunTrailEarth) + ]], + Documentation = [[ + Adds a trail for the sun, if an argument is provided, that date will be used instead of now + ]], + GuiPath = "/Night Sky/Sun Trails", + IsLocal = false +} + + +asset.onInitialize(function() + openspace.action.registerAction(AddSunTrail) +end) + +asset.onDeinitialize(function() + openspace.action.removeAction(AddSunTrail) +end) + +asset.export("AddSunTrail", AddSunTrail.Identifier) diff --git a/data/assets/actions/nightsky/misc.asset b/data/assets/actions/nightsky/misc.asset new file mode 100644 index 0000000000..97064c93ac --- /dev/null +++ b/data/assets/actions/nightsky/misc.asset @@ -0,0 +1,112 @@ +local textures = asset.resource({ + Name = "Cardinal Directions Textures", + Type = "HttpSynchronization", + Identifier = "cardinal_directions_textures", + Version = 1 +}) + + +local FadeInConstellationLabels = { + Identifier = "os.nightsky.FadeInConstellationLabels", + Name = "Fade In Constellation Labels", + Command = [[openspace.fadeIn("Scene.Constellations.Renderable.Labels",nil)]], + Documentation = "Fades in the constllation labels", + GuiPath = "/Constellations/Lines", + IsLocal = false +} + +local FadeOutConstellationLabels = { + Identifier = "os.nightsky.FadeOutConstellationLabels", + Name = "Fade Out Constellation Labels", + Command = [[openspace.fadeOut("Scene.Constellations.Renderable.Labels")]], + Documentation = "Fades out the constellation labels", + GuiPath = "/Constellations/Lines", + IsLocal = false +} + +local ShowConstellationElements = { + Identifier = "os.nightsky.ShowConstellationElements", + Name = "Show Constellation Elements", + Command = [[ + openspace.setPropertyValueSingle('Scene.Constellations.Renderable.DrawElements', true) + openspace.setPropertyValueSingle('Scene.Constellations.Renderable.Fade', 0) + local fadeSpeed = openspace.propertyValue("OpenSpaceEngine.FadeDuration") + openspace.fadeIn("Scene.Constellations.Renderable", fadeSpeed, "") + ]], + Documentation = "Shows the constellation lines with consideration of label state", + GuiPath = "/Constellations/Lines", + IsLocal = false +} + +local HideAllMarkings = { + Identifier = "os.nightsky.HideAllMarkings", + Name = "Hide All Markings", + Command = [[ + openspace.fadeOut("Scene.Constellations.Renderable") + openspace.fadeOut("{nightsky_marking}") + openspace.fadeOut("{du_grid}") + openspace.fadeOut("{du_grid_labels}") + openspace.fadeOut("{image_constellation}") + ]], + Documentation = "Hides all markings in the night sky", + GuiPath = "/Night Sky/Markings", + IsLocal = false +} + +local AddTickMarksBand = { + Identifier = "os.nightsky.AddNeswBandMarks", + Name = "Add a band to cardinal directions", + Command = [[ + local tex = openspace.propertyValue("Scene.CardinalDirectionSphere.Renderable.Texture") + if (string.find(tex, "small")) then + openspace.setPropertyValueSingle("Scene.CardinalDirectionSphere.Renderable.Texture", "]].. textures:gsub("\\","/") .. [[nesw_lines_red_small.png") + else + openspace.setPropertyValueSingle("Scene.CardinalDirectionSphere.Renderable.Texture", "]].. textures:gsub("\\","/") .. [[nesw_lines_red.png") + end + ]], + Documentation = "Adds tick marks to the cardinal directions", + GuiPath = "/Night Sky/Directions", + IsLocal = false +} + +local RemoveTickMarksBand = { + Identifier = "os.nightsky.RemoveNeswBandMarks", + Name = "Add a band to cardinal directions", + Command = [[ + local tex = openspace.propertyValue("Scene.CardinalDirectionSphere.Renderable.Texture") + if (string.find(tex, "small")) then + openspace.setPropertyValueSingle("Scene.CardinalDirectionSphere.Renderable.Texture", "]].. textures:gsub("\\","/") .. [[nesw_red_small.png") + else + openspace.setPropertyValueSingle("Scene.CardinalDirectionSphere.Renderable.Texture", "]].. textures:gsub("\\","/") .. [[nesw_red.png") + end + ]], + Documentation = "Removes tick marks to the cardinal directions", + GuiPath = "/Night Sky/Directions", + IsLocal = false +} + + +asset.onInitialize(function() + openspace.action.registerAction(FadeInConstellationLabels) + openspace.action.registerAction(FadeOutConstellationLabels) + openspace.action.registerAction(ShowConstellationElements) + openspace.action.registerAction(HideAllMarkings) + openspace.action.registerAction(AddTickMarksBand) + openspace.action.registerAction(RemoveTickMarksBand) +end) + +asset.onDeinitialize(function() + openspace.action.removeAction(RemoveTickMarksBand) + openspace.action.removeAction(AddTickMarksBand) + openspace.action.removeAction(HideAllMarkings) + openspace.action.removeAction(ShowConstellationElements) + openspace.action.removeAction(FadeOutConstellationLabels) + openspace.action.removeAction(FadeInConstellationLabels) +end) + +asset.export("FadeInConstellationLabels", FadeInConstellationLabels.Identifier) +asset.export("FadeOutConstellationLabels", FadeOutConstellationLabels.Identifier) +asset.export("ShowConstellationElements", ShowConstellationElements.Identifier) +asset.export("HideAllMarkings", HideAllMarkings.Identifier) +asset.export("AddTickMarksBand", AddTickMarksBand.Identifier) +asset.export("RemoveTickMarksBand", RemoveTickMarksBand.Identifier) diff --git a/data/assets/actions/nightsky/position.asset b/data/assets/actions/nightsky/position.asset new file mode 100644 index 0000000000..a976f230cd --- /dev/null +++ b/data/assets/actions/nightsky/position.asset @@ -0,0 +1,59 @@ +local NorthPole = { + Identifier = "os.nightsky.position.NorthPole", + Name = "Jump to the North Pole", + Command = [[ + openspace.navigation.jumpToGeo("Earth", 90.0001, 0.0001, 500) + local script = 'local wait = openspace.propertyValue("NavigationHandler.JumpToFadeDuration")openspace.action.triggerAction("os.nightsky.LookUp");openspace.setPropertyValueSingle("RenderEngine.BlackoutFactor", 1, wait)' + local wait = openspace.propertyValue("NavigationHandler.JumpToFadeDuration") + openspace.scheduleScript(script, wait + 0.1) + ]], + Documentation = "", + GuiPath = "/Night Sky/Position", + IsLocal = false +} + +local SouthPole = { + Identifier = "os.nightsky.position.SouthPole", + Name = "Jump to the South Pole", + Command = [[ + openspace.navigation.jumpToGeo("Earth", -89.9, 0.001, 2800); + local script = 'local wait = openspace.propertyValue("NavigationHandler.JumpToFadeDuration")openspace.action.triggerAction("os.nightsky.LookUp");openspace.setPropertyValueSingle("RenderEngine.BlackoutFactor", 1, wait)' + local wait = openspace.propertyValue("NavigationHandler.JumpToFadeDuration") + openspace.scheduleScript(script, wait + 0.1) + ]], + Documentation = "", + GuiPath = "/Night Sky/Position", + IsLocal = false +} + +local Equator = { + Identifier = "os.nightsky.position.Equator", + Name = "Jump to the Equator", + Command = [[ + local _, long, _ = openspace.globebrowsing.geoPositionForCamera(false); + openspace.navigation.jumpToGeo("Earth", 0.0001, long, 500); + local script = 'local wait = openspace.propertyValue("NavigationHandler.JumpToFadeDuration")openspace.action.triggerAction("os.nightsky.LookUp");openspace.setPropertyValueSingle("RenderEngine.BlackoutFactor", 1, wait)' + local wait = openspace.propertyValue("NavigationHandler.JumpToFadeDuration") + openspace.scheduleScript(script, wait + 0.1) + ]], + Documentation = "", + GuiPath = "/Night Sky/Position", + IsLocal = false +} + + +asset.onInitialize(function() + openspace.action.registerAction(NorthPole) + openspace.action.registerAction(SouthPole) + openspace.action.registerAction(Equator) +end) + +asset.onDeinitialize(function() + openspace.action.removeAction(Equator) + openspace.action.removeAction(SouthPole) + openspace.action.removeAction(NorthPole) +end) + +asset.export("NorthPole", NorthPole.Identifier) +asset.export("SouthPole", SouthPole.Identifier) +asset.export("Equator", Equator.Identifier) diff --git a/data/assets/actions/planets/lock_temporal_layer.asset b/data/assets/actions/planets/lock_temporal_layer.asset new file mode 100644 index 0000000000..8657d3da9c --- /dev/null +++ b/data/assets/actions/planets/lock_temporal_layer.asset @@ -0,0 +1,83 @@ +local LockCurrent = { + Identifier = "os.temporalLayer.LockCurrent", + Name = "Lock Focus Node Temporal Layers", + Command = [[ + local j2000 = openspace.time.currentTime() + local dateTime = openspace.time.convertTime(j2000) + local focusName = openspace.propertyValue("NavigationHandler.OrbitalNavigator.Anchor") + openspace.setPropertyValue("Scene." .. focusName .. ".*.FixedTime", dateTime) + openspace.setPropertyValue("Scene." .. focusName .. ".*.UseFixedTime", true) + ]], + Documentation = [[Set fixed date for all temporal layers for the currently + focused node.]], + GuiPath = "/Solar System", + IsLocal = false +} + +local UnlockCurrent = { + Identifier = "os.temporalLayer.UnlockCurrent", + Name = "Unlock Focus Node Temporal Layers", + Command = [[ + local j2000 = openspace.time.currentTime() + local dateTime = openspace.time.convertTime(j2000) + local focusName = openspace.propertyValue("NavigationHandler.OrbitalNavigator.Anchor") + openspace.setPropertyValue("Scene." .. focusName .. ".*.UseFixedTime", false) + openspace.setPropertyValue("Scene." .. focusName .. ".*.FixedTime", "") + ]], + Documentation = [[Removes fixed date for all temporal layers for the currently + focused node.]], + GuiPath = "/Solar System", + IsLocal = false +} + +local LockAll = { + Identifier = "os.temporalLayer.LockAll", + Name = "Lock All Temporal Layers", + Command = [[ + local j2000 = openspace.time.currentTime() + local dateTime = openspace.time.convertTime(j2000) + openspace.setPropertyValue("Scene.*.FixedTime", dateTime) + openspace.setPropertyValue("Scene.*.UseFixedTime", true) + ]], + Documentation = "Set fixed date for all temporal layers in the scene.", + GuiPath = "/Solar System", + IsLocal = false +} + +local UnlockAll = { + Identifier = "os.temporalLayer.UnlockAll", + Name = "Unlock All Temporal Layers", + Command = [[ + openspace.setPropertyValue("Scene.*.UseFixedTime", false) + openspace.setPropertyValue("Scene.*.FixedTime", "") + ]], + Documentation = "Removes fixed date for all temporal layers in the scene.", + GuiPath = "/Solar System", + IsLocal = false +} + + +asset.onInitialize(function() + openspace.action.registerAction(LockCurrent); + openspace.action.registerAction(UnlockCurrent); + openspace.action.registerAction(LockAll); + openspace.action.registerAction(UnlockAll); +end) + +asset.onDeinitialize(function() + openspace.action.removeAction(UnlockAll); + openspace.action.removeAction(LockAll); + openspace.action.removeAction(UnlockCurrent); + openspace.action.removeAction(LockCurrent); +end) + + +asset.meta = { + Name = "Temporal Layers - Lock Date", + Version = "1.0", + Description = [[Provides actions for locking and unlocking temporal layers to the + current date.]], + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/actions/planets/planet_lighting.asset b/data/assets/actions/planets/planet_lighting.asset index 95da0b5b6c..d2f13e56c7 100644 --- a/data/assets/actions/planets/planet_lighting.asset +++ b/data/assets/actions/planets/planet_lighting.asset @@ -90,8 +90,10 @@ local AllGlobesGlobalIllumination = { Identifier = "os.AllGlobesGlobalIllumination", Name = "All globes global illumination", Command = [[ - openspace.setPropertyValue("{planet_solarSystem}.Renderable.PerformShading", false) - openspace.setPropertyValue("{moon_solarSystem}.Renderable.PerformShading", false) + local allGlobes = openspace.nodeByRenderableType("RenderableGlobe") + for _, globe in ipairs(allGlobes) do + openspace.setPropertyValue("Scene." .. globe .. ".Renderable.PerformShading", false) + end openspace.setPropertyValue("Scene.*Atmosphere.Renderable.SunFollowingCamera", true) openspace.setPropertyValue("Scene.*.Renderable.ShadowsComponent.DistanceFraction", 3000) openspace.setPropertyValue("Scene.Earth.Renderable.Layers.NightLayers.Earth_at_Night_2012.Enabled", false) @@ -105,8 +107,10 @@ local AllGlobesStandardIllumination = { Identifier = "os.AllGlobesStandardIllumination", Name = "All globes standard illumination", Command = [[ - openspace.setPropertyValue("{planet_solarSystem}.Renderable.PerformShading", true) - openspace.setPropertyValue("{moon_solarSystem}.Renderable.PerformShading", true) + local allGlobes = openspace.nodeByRenderableType("RenderableGlobe") + for _, globe in ipairs(allGlobes) do + openspace.setPropertyValue("Scene." .. globe .. ".Renderable.PerformShading", true) + end openspace.setPropertyValue("Scene.*Atmosphere.Renderable.SunFollowingCamera", false) openspace.setPropertyValue("Scene.*.Renderable.ShadowsComponent.DistanceFraction", 40) openspace.setPropertyValueSingle("Scene.Earth.Renderable.Layers.NightLayers.Earth_at_Night_2012.Enabled", true) diff --git a/data/assets/actions/solarsystem_actions.asset b/data/assets/actions/solarsystem_actions.asset new file mode 100644 index 0000000000..6d1a891d0e --- /dev/null +++ b/data/assets/actions/solarsystem_actions.asset @@ -0,0 +1,6 @@ +asset.require("actions/trails/toggle_all_trails") +asset.require("actions/trails/toggle_trails_planets_moons") +asset.require("actions/planets/planet_lighting") +asset.require("actions/system/undo_event_fades") +asset.require("actions/trails/toggle_all_minor_moon_trails") +asset.require("actions/trails/on_off_all_minor_moons") diff --git a/data/assets/actions/time.asset b/data/assets/actions/time.asset index a33d22ca24..cdea4c4e1e 100644 --- a/data/assets/actions/time.asset +++ b/data/assets/actions/time.asset @@ -31,14 +31,92 @@ openspace.time.setTime(openspace.time.advancedTime(openspace.time.currentTime(), IsLocal = false } +local SiderealWeekIncrease = { + Identifier = "os.time.siderealWeekIncrease", + Name = "Advance 1 sidereal week", + Command = [[ + openspace.time.setTime(openspace.time.advancedTime(openspace.time.currentTime(), 86164.0905 * 7)); + ]], + Documentation = [[Advances time by a sidereal week (Instant)]], + GuiPath = "/Time", + IsLocal = false +} + +local SiderealWeekDecrease = { + Identifier = "os.time.siderealWeekDecrease", + Name = "Decrement 1 sidereal week", + Command = [[ + openspace.time.setTime(openspace.time.advancedTime(openspace.time.currentTime(), -86164.0905 * 7)); + ]], + Documentation = [[Decrements time by a sidereal week (Instant)]], + GuiPath = "/Time", + IsLocal = false +} + +local SolarDayIncrease = { + Identifier = "os.time.SolarDayIncrease", + Name = "Advance 1 solar day", + Command = [[ + openspace.time.setTime(openspace.time.advancedTime(openspace.time.UTC(), "1d")); + ]], + Documentation = [[Advances time by a solar day (Instant)]], + GuiPath = "/Time", + IsLocal = false +} + +local SolarDayDecrease = { + Identifier = "os.time.SolarDayDecrease", + Name = "Decrement 1 solar day", + Command = [[ + openspace.time.setTime(openspace.time.advancedTime(openspace.time.UTC(), "-1d")); + ]], + Documentation = [[Decrements time by a solar day (Instant)]], + GuiPath = "/Time", + IsLocal = false +} + +local SolarWeekIncrease = { + Identifier = "os.time.SolarWeekIncrease", + Name = "Advance 1 solar week", + Command = [[ + openspace.time.setTime(openspace.time.advancedTime(openspace.time.UTC(), "7d")); + ]], + Documentation = [[Advances time by a solar week (Instant)]], + GuiPath = "/Time", + IsLocal = false +} + +local SolarWeekDecrease = { + Identifier = "os.time.SolarWeekDecrease", + Name = "Decrement 1 solar week", + Command = [[ + openspace.time.setTime(openspace.time.advancedTime(openspace.time.UTC(), "-7d")); + ]], + Documentation = [[Decrements time by a solar week (Instant)]], + GuiPath = "/Time", + IsLocal = false +} + asset.onInitialize(function() openspace.action.registerAction(ReverseRate) openspace.action.registerAction(SiderealDayIncrease) openspace.action.registerAction(SiderealDayDecrease) + openspace.action.registerAction(SiderealWeekIncrease) + openspace.action.registerAction(SiderealWeekDecrease) + openspace.action.registerAction(SolarDayIncrease) + openspace.action.registerAction(SolarDayDecrease) + openspace.action.registerAction(SolarWeekIncrease) + openspace.action.registerAction(SolarWeekDecrease) end) asset.onDeinitialize(function() + openspace.action.removeAction(SolarWeekDecrease) + openspace.action.removeAction(SolarWeekIncrease) + openspace.action.removeAction(SolarDayDecrease) + openspace.action.removeAction(SolarDayIncrease) + openspace.action.removeAction(SiderealWeekDecrease) + openspace.action.removeAction(SiderealWeekIncrease) openspace.action.removeAction(SiderealDayDecrease) openspace.action.removeAction(SiderealDayIncrease) openspace.action.removeAction(ReverseRate) @@ -47,6 +125,12 @@ end) asset.export("ReverseRate", ReverseRate.Identifier) asset.export("SiderealDayIncrease", SiderealDayIncrease.Identifier) asset.export("SiderealDayDecrease", SiderealDayDecrease.Identifier) +asset.export("SiderealWeekIncrease", SiderealWeekIncrease.Identifier) +asset.export("SiderealWeekDecrease", SiderealWeekDecrease.Identifier) +asset.export("SolarDayIncrease", SolarDayIncrease.Identifier) +asset.export("SolarDayDecrease", SolarDayDecrease.Identifier) +asset.export("SolarWeekIncrease", SolarWeekIncrease.Identifier) +asset.export("SolarWeekDecrease", SolarWeekDecrease.Identifier) diff --git a/data/assets/actions/trails/on_off_all_minor_moons.asset b/data/assets/actions/trails/on_off_all_minor_moons.asset index 5f680e6dae..dcc975e14f 100644 --- a/data/assets/actions/trails/on_off_all_minor_moons.asset +++ b/data/assets/actions/trails/on_off_all_minor_moons.asset @@ -2,21 +2,8 @@ local MinorMoonsOn = { Identifier = "os.MinorMoonsOn", Name = "Turn on minor moons and trails", Command = [[ - local trails = openspace.property("{moonTrail_minor}.Renderable.Enabled") - local trails_fade = openspace.property("{moonTrail_minor}.Renderable.Fade") - - local moons = openspace.property("{moon_minor}.Renderable.Enabled") - local moons_fade = openspace.property("{moon_minor}.Renderable.Fade") - - for i, v in pairs(trails_fade) do - openspace.setPropertyValueSingle(trails[i], true) - openspace.setPropertyValueSingle(v, 1, 2, "Linear") - end - - for i, v in pairs(moons_fade) do - openspace.setPropertyValueSingle(moons[i], true) - openspace.setPropertyValueSingle(v, 1, 2, "Linear") - end + openspace.fadeIn("{moonTrail_minor}.Renderable") + openspace.fadeIn("{moon_minor}.Renderable") ]], Documentation = "Turn ON minor moons and their trails for all planets in the solar system", GuiPath = "/Solar System/Minor Moons", @@ -27,31 +14,8 @@ local MinorMoonsOff = { Identifier = "os.MinorMoonsOff", Name = "Turn off minor moons and trails", Command = [[ - local trails = openspace.property("{moonTrail_minor}.Renderable.Enabled") - local trails_fade = openspace.property("{moonTrail_minor}.Renderable.Fade") - - local moons = openspace.property("{moon_minor}.Renderable.Enabled") - local moons_fade = openspace.property("{moon_minor}.Renderable.Fade") - - for i, v in pairs(trails_fade) do - openspace.setPropertyValueSingle( - v, - 0, - 2, - "Linear", - "openspace.setPropertyValueSingle('" .. trails[i] .. "', false)" - ) - end - - for i, v in pairs(moons_fade) do - openspace.setPropertyValueSingle( - v, - 0, - 2, - "Linear", - "openspace.setPropertyValueSingle('" .. moons[i] .. "', false)" - ) - end + openspace.fadeOut("{moonTrail_minor}.Renderable") + openspace.fadeOut("{moon_minor}.Renderable") ]], Documentation = "Turn OFF minor moons and their trails for all planets in the solar system", GuiPath = "/Solar System/Minor Moons", @@ -76,7 +40,7 @@ asset.export("MinorMoonsOff", MinorMoonsOff.Identifier) asset.meta = { Name = "Actions - Turn ON/OFF all Minor Moons", - Description = "Asset providing actions to turn ON/OFF all minor moons and their trails", + Description = "Asset providing actions to turn ON/OFF all minor moons and their trails", Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/actions/trails/toggle_all_dwarf_planet_trails.asset b/data/assets/actions/trails/toggle_all_dwarf_planet_trails.asset index 529e552c86..a352e3ac52 100644 --- a/data/assets/actions/trails/toggle_all_dwarf_planet_trails.asset +++ b/data/assets/actions/trails/toggle_all_dwarf_planet_trails.asset @@ -1,12 +1,7 @@ local ToggleDwarfPlanetTrails = { Identifier = "os.ToggleDwarfPlanetTrails", Name = "Toggle dwarf planet trails", - Command = [[ - local list = openspace.property("{planetTrail_dwarf}.Renderable.Enabled") - for _,v in pairs(list) do - openspace.setPropertyValueSingle(v, not openspace.propertyValue(v)) - end - ]], + Command = [[openspace.toggleFade("{planetTrail_dwarf}.Renderable")]], Documentation = "Toggle on/off trails for all dwarf planets in the solar system", GuiPath = "/Trails", IsLocal = false diff --git a/data/assets/actions/trails/toggle_all_minor_moon_trails.asset b/data/assets/actions/trails/toggle_all_minor_moon_trails.asset index 0b442deed4..26add1ac2d 100644 --- a/data/assets/actions/trails/toggle_all_minor_moon_trails.asset +++ b/data/assets/actions/trails/toggle_all_minor_moon_trails.asset @@ -1,12 +1,7 @@ local ToggleMinorMoonTrails = { Identifier = "os.ToggleMinorMoonTrails", Name = "Toggle minor moon trails", - Command = [[ - local list = openspace.property("{moonTrail_minor}.Renderable.Enabled") - for _,v in pairs(list) do - openspace.setPropertyValueSingle(v, not openspace.propertyValue(v)) - end - ]], + Command = [[openspace.toggleFade("{moonTrail_minor}.Renderable")]], Documentation = "Toggle on/off minor moon trails for all planets in the solar system", GuiPath = "/Trails", IsLocal = false diff --git a/data/assets/actions/trails/toggle_all_trails.asset b/data/assets/actions/trails/toggle_all_trails.asset index a9efd1fb4a..1dae3be815 100644 --- a/data/assets/actions/trails/toggle_all_trails.asset +++ b/data/assets/actions/trails/toggle_all_trails.asset @@ -2,14 +2,8 @@ local FadeUpTrails = { Identifier = "os.FadeUpTrails", Name = "Show all trails", Command = [[ - local capList = openspace.property("Scene.*Trail.Renderable.Fade") - for _,v in ipairs(capList) do - openspace.setPropertyValueSingle(v, 1, 2) - end - local list = openspace.property("Scene.*trail.Renderable.Fade") - for _,v in ipairs(list) do - openspace.setPropertyValueSingle(v, 1, 2) - end + openspace.fadeIn("Scene.*Trail.Renderable") + openspace.fadeIn("Scene.*trail.Renderable") ]], Documentation = "Fade up all enabled trails in the Scene", GuiPath = "/Trails", @@ -20,14 +14,8 @@ local FadeDownTrails = { Identifier = "os.FadeDownTrails", Name = "Hide all trails", Command = [[ - local capList = openspace.property("Scene.*Trail.Renderable.Fade") - for _,v in ipairs(capList) do - openspace.setPropertyValueSingle(v, 0, 2) - end - local list = openspace.property("Scene.*trail.Renderable.Fade") - for _,v in ipairs(list) do - openspace.setPropertyValueSingle(v, 0, 2) - end + openspace.fadeOut("Scene.*Trail.Renderable") + openspace.fadeOut("Scene.*trail.Renderable") ]], Documentation = "Fade down all enabled trails in the Scene", GuiPath = "/Trails", @@ -38,30 +26,8 @@ local ToggleTrails = { Identifier = "os.ToggleTrails", Name = "Toggle all trails", Command = [[ - local capList = openspace.property("*Trail.Renderable.Fade") - local list = openspace.property("*trail.Renderable.Fade") - if (#capList == 0) and (#list == 0) then - openspace.printWarning("No trails to toggle") - else - local prop - if #capList > 0 then - prop = capList[1] - else - prop = list[1] - end - local currentFade = openspace.propertyValue(prop) - local newFade = 0 - if currentFade < 1 then - newFade = 1 - end - if (#capList > 0) then - openspace.setPropertyValue("Scene.*Trail.Renderable.Fade", newFade, 2) - end - if (#list > 0) then - openspace.setPropertyValue("Scene.*trail.Renderable.Fade", newFade, 2) - end - openspace.setPropertyValue("Scene.*TrailEarth.Renderable.Fade", newFade, 2) - end + openspace.toggleFade("Scene.*Trail.Renderable") + openspace.toggleFade("Scene.*trail.Renderable") ]], Documentation = "Toggle fade for all trails in the Scene", GuiPath = "/Trails", @@ -72,29 +38,8 @@ local ToggleTrailsInstant = { Identifier = "os.ToggleTrailsInstant", Name = "Toggle all trails instantly", Command = [[ - local capList = openspace.property("*Trail.Renderable.Fade") - local list = openspace.property("*trail.Renderable.Fade") - if (#capList == 0) and (#list == 0) then - openspace.printWarning("No trails to toggle") - else - local prop - if #capList > 0 then - prop = capList[1] - else - prop = list[1] - end - local currentFade = openspace.propertyValue(prop) - local newFade = 0 - if currentFade < 1 then - newFade = 1 - end - if (#capList > 0) then - openspace.setPropertyValue("Scene.*Trail.Renderable.Fade", newFade) - end - if (#list > 0) then - openspace.setPropertyValue("Scene.*trail.Renderable.Fade", newFade) - end - end + openspace.toggleFade("Scene.*Trail.Renderable", 0.0) + openspace.toggleFade("Scene.*trail.Renderable", 0.0) ]], Documentation = "Toggle fade instantly for all trails in the Scene", GuiPath = "/Trails", diff --git a/data/assets/actions/trails/toggle_all_trails_planets_moons_instant.asset b/data/assets/actions/trails/toggle_all_trails_planets_moons_instant.asset index a351ddb0ef..03316770bf 100644 --- a/data/assets/actions/trails/toggle_all_trails_planets_moons_instant.asset +++ b/data/assets/actions/trails/toggle_all_trails_planets_moons_instant.asset @@ -2,15 +2,8 @@ local ToggleTrailsInstant = { Identifier = "os.ToggleTrailsInstant", Name = "Toggle planet and moon trails (instant)", Command = [[ - local list = openspace.property("{planetTrail_solarSystem}.Renderable.Enabled") - for _,v in pairs(list) do - openspace.setPropertyValueSingle(v, not openspace.propertyValue(v)) - end - - local moonlist = openspace.property("{moonTrail_solarSystem}.Renderable.Enabled") - for _,v in pairs(moonlist) do - openspace.setPropertyValueSingle(v, not openspace.propertyValue(v)) - end + openspace.toggleFade("{planetTrail_solarSystem}.Renderable", 0.0) + openspace.toggleFade("{moonTrail_solarSystem}.Renderable", 0.0) ]], Documentation = "Toggles the visibility of planet and moon trails", GuiPath = "/Solar System", diff --git a/data/assets/actions/trails/toggle_trails_planets_moons.asset b/data/assets/actions/trails/toggle_trails_planets_moons.asset index 0a65d1618c..bf12f34988 100644 --- a/data/assets/actions/trails/toggle_trails_planets_moons.asset +++ b/data/assets/actions/trails/toggle_trails_planets_moons.asset @@ -2,8 +2,8 @@ local FadeUpTrails = { Identifier = "os.planetsmoons.FadeUpTrails", Name = "Show planet and moon trails", Command = [[ - openspace.setPropertyValue("{planetTrail_solarSystem}.Renderable.Fade", 1, 2) - openspace.setPropertyValue("{moonTrail_solarSystem}.Renderable.Fade", 1, 2) + openspace.fadeIn("{planetTrail_solarSystem}.Renderable") + openspace.fadeIn("{moonTrail_solarSystem}.Renderable") ]], Documentation = "Fade up all planet and moon trails in the Scene", GuiPath = "/Trails", @@ -14,8 +14,8 @@ local FadeDownTrails = { Identifier = "os.planetsmoons.FadeDownTrails", Name = "Hide planet and moon trails", Command = [[ - openspace.setPropertyValue("{planetTrail_solarSystem}.Renderable.Fade", 0, 2) - openspace.setPropertyValue("{moonTrail_solarSystem}.Renderable.Fade", 0, 2) + openspace.fadeOut("{planetTrail_solarSystem}.Renderable") + openspace.fadeOut("{moonTrail_solarSystem}.Renderable") ]], Documentation = "Fade down all planet and moon trails in the Scene", GuiPath = "/Trails", @@ -26,25 +26,8 @@ local ToggleTrails = { Identifier = "os.planetsmoons.ToggleTrails", Name = "Toggle planet and moon trails", Command = [[ - local capList = openspace.property("{planetTrail_solarSystem}.Renderable.Fade") - local list = openspace.property("{moonTrail_solarSystem}.Renderable.Fade") - if (#capList == 0) and (#list == 0) then - openspace.printWarning("No trails to toggle") - else - local prop - if (#capList > 0) then - prop = capList[1] - else - prop = list[1] - end - local currentFade = openspace.propertyValue(prop) - local newFade = 0 - if currentFade < 1 then - newFade = 1 - end - openspace.setPropertyValue("{planetTrail_solarSystem}.Renderable.Fade", newFade, 2) - openspace.setPropertyValue("{moonTrail_solarSystem}.Renderable.Fade", newFade, 2) - end + openspace.toggleFade("{planetTrail_solarSystem}.Renderable.Fade") + openspace.toggleFade("{moonTrail_solarSystem}.Renderable.Fade") ]], Documentation = "Toggle fade for planet and moon trails in the Scene", GuiPath = "/Trails", diff --git a/data/assets/base.asset b/data/assets/base.asset index b82a1f30e6..a7ec2d5e95 100644 --- a/data/assets/base.asset +++ b/data/assets/base.asset @@ -38,47 +38,11 @@ else asset.require("scene/solarsystem/planets/default_layers") end -asset.require("scene/digitaluniverse/2dF") -asset.require("scene/digitaluniverse/2mass") -asset.require("scene/digitaluniverse/6dF") -asset.require("scene/digitaluniverse/abell") -asset.require("scene/digitaluniverse/allsky_hydrogenalpha") -asset.require("scene/digitaluniverse/allsky_visible") -asset.require("scene/digitaluniverse/alternatestarlabels") -asset.require("scene/digitaluniverse/backgroundradiation") -asset.require("scene/digitaluniverse/brown_dwarfs") -asset.require("scene/digitaluniverse/galaxy_clusters") -asset.require("scene/digitaluniverse/constellationbounds") -asset.require("scene/digitaluniverse/constellations") -asset.require("scene/digitaluniverse/exoplanets") -asset.require("scene/digitaluniverse/exoplanets_candidates") -asset.require("scene/digitaluniverse/globularclusters") -asset.require("scene/digitaluniverse/grids") -asset.require("scene/digitaluniverse/galaxy_groups") -asset.require("scene/digitaluniverse/h2regions") -asset.require("scene/digitaluniverse/local_group_dwarfs") -asset.require("scene/digitaluniverse/milkyway") -asset.require("scene/digitaluniverse/milkyway_arm_labels") -asset.require("scene/digitaluniverse/milkyway_label") -asset.require("scene/digitaluniverse/obassociations") -asset.require("scene/digitaluniverse/oort_cloud") -asset.require("scene/digitaluniverse/openclusters") -asset.require("scene/digitaluniverse/planetarynebulae") -asset.require("scene/digitaluniverse/pulsars") -asset.require("scene/digitaluniverse/quasars") -asset.require("scene/digitaluniverse/star_uncertainty") -asset.require("scene/digitaluniverse/starlabels") -asset.require("scene/digitaluniverse/starorbits") -asset.require("scene/digitaluniverse/stars") -asset.require("scene/digitaluniverse/superclusters") -asset.require("scene/digitaluniverse/supernovaremnants") -asset.require("scene/digitaluniverse/tully") -asset.require("scene/digitaluniverse/voids") -asset.require("scene/digitaluniverse/white_dwarfs") +asset.require("scene/digitaluniverse/digitaluniverse") asset.require("nightsky/nightsky") asset.require("customization/globebrowsing") -asset.require("actions/default_actions") +asset.require("actions/solarsystem_actions") asset.require("modules/exoplanets/exoplanets") asset.require("modules/skybrowser/skybrowser") diff --git a/data/assets/base_blank.asset b/data/assets/base_blank.asset index e4ec936782..773736895f 100644 --- a/data/assets/base_blank.asset +++ b/data/assets/base_blank.asset @@ -4,11 +4,10 @@ asset.require("spice/core") asset.require("dashboard/default_dashboard") --- Load default key bindings applicable to most scenes -asset.require("./default_keybindings") --- Load web gui -local webGui = asset.require("util/webgui") +-- Load default actions and key bindings applicable to most scenes +asset.require("actions/default_actions") +asset.require("./default_keybindings") -- Scale the different UI components based on the operating system's DPI scaling value asset.require("util/dpiscaling") @@ -19,8 +18,12 @@ asset.require("util/launcher_images") -- Modules and component settings asset.require("modules/touch/default_settings") +-- Load web gui +local webGui = asset.require("util/webgui") + asset.onInitialize(function() - webGui.setCefRoute("onscreen") - openspace.setPropertyValueSingle("RenderEngine.VerticalLogOffset", 0.100000) + openspace.setPropertyValueSingle("RenderEngine.VerticalLogOffset", 0.1) + openspace.setPropertyValueSingle("Dashboard.StartPositionOffset", { 15.0, 49.0 }) + openspace.setPropertyValueSingle("RenderEngine.ShowCamera", false) end) diff --git a/data/assets/base_keybindings.asset b/data/assets/base_keybindings.asset index ce49ac2117..da88eafd0c 100644 --- a/data/assets/base_keybindings.asset +++ b/data/assets/base_keybindings.asset @@ -7,12 +7,7 @@ local allTrailsInstantAction = asset.require("actions/trails/toggle_all_trails") local TogglePlanetLabels = { Identifier = "os_default.TogglePlanetLabels", Name = "Toggle planet labels", - Command = [[ - local list = openspace.property("{solarsystem_labels}.Renderable.Enabled") - for _,v in pairs(list) do - openspace.setPropertyValueSingle(v, not openspace.propertyValue(v)) - end - ]], + Command = [[openspace.toggleFade("{solarsystem_labels}.Renderable")]], Documentation = "Turns on visibility for all solar system labels", GuiPath = "/Solar System", IsLocal = false diff --git a/data/assets/customization/gui.asset b/data/assets/customization/gui.asset index 7f49e78549..d981cc4a3c 100644 --- a/data/assets/customization/gui.asset +++ b/data/assets/customization/gui.asset @@ -3,9 +3,9 @@ asset.export("webguiDevelopmentMode", false) -- To make changes to the webgui: -- 1) Set the above `webguiDevelopmentMode` to true --- 2) Clone the repository: https://github.com/OpenSpace/OpenSpace-WebGuiFrontend +-- 2) Clone the repository: https://github.com/OpenSpace/OpenSpace-WebGui -- 3) Install nodejs (including npm) --- 4) Within the repository, run `npm install` and `npm start` +-- 4) Within the repository, run `npm install` and `npm run dev` asset.meta = { diff --git a/data/assets/dashboard/distance.asset b/data/assets/dashboard/distance.asset index 6da0e66915..f87938d8e5 100644 --- a/data/assets/dashboard/distance.asset +++ b/data/assets/dashboard/distance.asset @@ -1,7 +1,9 @@ local Item = { Type = "DashboardItemDistance", Identifier = "Distance", - GuiName = "Distance" + GuiName = "Distance", + SourceType = "Camera", + DestinationType = "Focus" } diff --git a/data/assets/default_keybindings.asset b/data/assets/default_keybindings.asset index 7137dfe9ff..f1bc42ccb6 100644 --- a/data/assets/default_keybindings.asset +++ b/data/assets/default_keybindings.asset @@ -1,348 +1,76 @@ -local propertyHelper = asset.require("util/property_helper") - - - -local ToggleNativeUi = { - Identifier = "os.ToggleNativeUi", - Name = "Show native GUI", - Command = propertyHelper.invert("Modules.ImGUI.Enabled"), - Documentation = "Shows or hides the native UI", - GuiPath = "/System/GUI", - IsLocal = true -} - -local ToggleShutdown = { - Identifier = "os.ToggleShutdown", - Name = "Toggle shutdown", - Command = "openspace.toggleShutdown()", - Documentation = [[ - Toggles the shutdown that will stop OpenSpace after a grace period. Press again to - cancel the shutdown during this period]], - GuiPath = "/System", - IsLocal = true -} - -local TakeScreenshot = { - Identifier = "os.TakeScreenshot", - Name = "Take screenshot", - Command = "openspace.takeScreenshot()", - Documentation = [[Saves the contents of the screen to a file in the ${SCREENSHOTS} - directory]], - GuiPath = "/System/Rendering", - IsLocal = true -} - -local TogglePauseInterpolated = { - Identifier = "os.TogglePauseInterpolated", - Name = "Toggle pause (interpolate)", - Command = "openspace.time.pauseToggleViaKeyboard()", - Documentation = "Smoothly starts and stops the simulation time", - GuiPath = "/Time/Simulation Speed", - IsLocal = true -} - -local TogglePauseImmediate = { - Identifier = "os.TogglePauseImmediate", - Name = "Toggle pause (immediate)", - Command = "openspace.time.togglePause()", - Documentation = "Immediately starts and stops the simulation time", - GuiPath = "/Time/Simulation Speed", - IsLocal = true -} - -local ToggleRotationFriction = { - Identifier = "os.ToggleRotationFriction", - Name = "Toggle rotation friction", - Command = propertyHelper.invert("NavigationHandler.OrbitalNavigator.Friction.RotationalFriction"), - Documentation = [[Toggles the rotational friction of the camera. If it is disabled, the - camera rotates around the focus object indefinitely]], - GuiPath = "/Navigation", - IsLocal = true -} - -local ToggleZoomFriction = { - Identifier = "os.ToggleZoomFriction", - Name = "Toggle zoom friction", - Command = propertyHelper.invert("NavigationHandler.OrbitalNavigator.Friction.ZoomFriction"), - Documentation = [[Toggles the zoom friction of the camera. If it is disabled, the camera - rises up from or closes in towards the focus object indefinitely]], - GuiPath = "/Navigation", - IsLocal = true -} - -local ToggleRollFriction = { - Identifier = "os.ToggleRollFriction", - Name = "Toggle roll friction", - Command = propertyHelper.invert("NavigationHandler.OrbitalNavigator.Friction.RollFriction"), - Documentation = [[Toggles the roll friction of the camera. If it is disabled, the camera - rolls around its own axis indefinitely]], - GuiPath = "/Navigation", - IsLocal = true -} - -local FadeToBlack = { - Identifier = "os.FadeToBlack", - Name = "Fade to/from black", - Command = [[ - if openspace.propertyValue("RenderEngine.BlackoutFactor") > 0.5 then - openspace.setPropertyValueSingle("RenderEngine.BlackoutFactor", 0.0, 3) - else - openspace.setPropertyValueSingle("RenderEngine.BlackoutFactor", 1.0, 3) - end - ]], - Documentation = [[Toggles the fade to black within 3 seconds or shows the rendering - after 3 seconds]], - GuiPath = "/Rendering", - IsLocal = false -} - -local ToggleMainGui = { - Identifier = "os.ToggleMainGui", - Name = "Toggle main GUI", - Command = propertyHelper.invert("Modules.CefWebGui.Visible"), - Documentation = "Toggles the main GUI", - GuiPath = "/System/GUI", - IsLocal = true -} - -local ToggleOverlays = { - Identifier = "os.ToggleOverlays", - Name = "Toggle dashboard and overlays", - Command = [[ - local isEnabled = openspace.propertyValue("Dashboard.IsEnabled") - openspace.setPropertyValueSingle("Dashboard.IsEnabled", not isEnabled) - openspace.setPropertyValueSingle("RenderEngine.ShowLog", not isEnabled) - openspace.setPropertyValueSingle("RenderEngine.ShowVersion", not isEnabled) - openspace.setPropertyValueSingle("RenderEngine.ShowCamera", not isEnabled) - ]], - Documentation = "Toggles the dashboard and overlays", - GuiPath = "/System/GUI", - IsLocal = true -} - -local ToggleMasterRendering = { - Identifier = "os.ToggleMasterRendering", - Name = "Toggle rendering on master", - Command = propertyHelper.invert("RenderEngine.DisableMasterRendering"), - Documentation = "Toggles the rendering on master", - GuiPath = "/System/Rendering", - IsLocal = true -} - -local NextDeltaStepInterpolate = { - Identifier = "os.NextDeltaStepInterpolate", - Name = "Next simulation time step (interpolate)", - Command = "openspace.time.interpolateNextDeltaTimeStep()", - Documentation = [[Smoothly interpolates the simulation speed to the next simulation time - step, if one exists]], - GuiPath = "/Time/Simulation Speed", - IsLocal = true -} - -local NextDeltaStepImmediate = { - Identifier = "os.NextDeltaStepImmediate", - Name = "Next simulation time step (immediate)", - Command = "openspace.time.setNextDeltaTimeStep()", - Documentation = [[Immediately set the simulation speed to the next simulation time step, - if one exists]], - GuiPath = "/Time/Simulation Speed", - IsLocal = true -} - -local PreviousDeltaStepInterpolate = { - Identifier = "os.PreviousDeltaStepInterpolate", - Name = "Previous simulation time step (interpolate)", - Command = "openspace.time.interpolatePreviousDeltaTimeStep()", - Documentation = [[Smoothly interpolates the simulation speed to the previous simulation - time step, if one exists]], - GuiPath = "/Time/Simulation Speed", - IsLocal = true -} - -local PreviousDeltaStepImmediate = { - Identifier = "os.PreviousDeltaStepImmediate", - Name = "Previous simulation time step (immediate)", - Command = "openspace.time.setPreviousDeltaTimeStep()", - Documentation = [[Immediately set the simulation speed to the previous simulation time - step, if one exists]], - GuiPath = "/Time/Simulation Speed", - IsLocal = true -} - -local RealTimeDeltaStepInterpolate = { - Identifier = "os.RealTimeDeltaStepInterpolate", - Name = "Reset the simulation time to realtime (interpolate)", - Command = "openspace.time.interpolateDeltaTime(1)", - Documentation = "Smoothly interpolate the simulation speed to match real-time speed", - GuiPath = "/Time/Simulation Speed", - IsLocal = true -} - -local RealTimeDeltaStepImmediate = { - Identifier = "os.RealTimeDeltaStepImmediate", - Name = "Reset the simulation time to realtime (immediate)", - Command = "openspace.time.setDeltaTime(1)", - Documentation = "Immediately set the simulation speed to match real-time speed", - GuiPath = "/Time/Simulation Speed", - IsLocal = true -} - -local DateToNowInterpolate = { - Identifier = "os.DateToNowInterpolate", - Name = "Set the in-game time to now (interpolate)", - Command = "openspace.time.interpolateTime(openspace.time.currentWallTime())", - Documentation = "Immediately set the current in-game time to the 'now' time", - GuiPath = "/Time/Simulation Speed", - IsLocal = true -} - -local DateToNowImmediate = { - Identifier = "os.DateToNowImmediate", - Name = "Set the in-game time to now (immediate)", - Command = "openspace.time.setTime(openspace.time.currentWallTime())", - Documentation = "Smoothly interpolate the current in-game time to the 'now' time", - GuiPath = "/Time/Simulation Speed", - IsLocal = true -} - -local ReloadGui = { - Identifier = "os.ReloadGui", - Name = "Reload GUI", - Command = [[openspace.setPropertyValueSingle("Modules.CefWebGui.Reload", nil)]], - Documentation = "Reloads the GUI", - GuiPath = "/System/GUI", - IsLocal = true -} +local actions = asset.require("actions/default_actions") asset.onInitialize(function() - openspace.action.registerAction(ToggleNativeUi) - openspace.bindKey("F1", ToggleNativeUi.Identifier) + openspace.bindKey("Ctrl+Q", actions.ToggleShutdown) - openspace.action.registerAction(ToggleShutdown) - openspace.bindKey("ESC", ToggleShutdown.Identifier) + openspace.bindKey("F12", actions.TakeScreenshot) + openspace.bindKey("PRINT_SCREEN", actions.TakeScreenshot) - openspace.action.registerAction(TakeScreenshot) - openspace.bindKey("F12", TakeScreenshot.Identifier) - openspace.bindKey("PRINT_SCREEN", TakeScreenshot.Identifier) + openspace.bindKey("SPACE", actions.TogglePauseInterpolated) + openspace.bindKey("Shift+SPACE", actions.TogglePauseImmediate) - openspace.action.registerAction(TogglePauseInterpolated) - openspace.bindKey("SPACE", TogglePauseInterpolated.Identifier) + openspace.bindKey("F", actions.ToggleRotationFriction) + openspace.bindKey("Shift+F", actions.ToggleZoomFriction) + openspace.bindKey("Ctrl+F", actions.ToggleRollFriction) - openspace.action.registerAction(TogglePauseImmediate) - openspace.bindKey("Shift+SPACE", TogglePauseImmediate.Identifier) + openspace.bindKey("B", actions.FadeToBlack) - openspace.action.registerAction(ToggleRotationFriction) - openspace.bindKey("F", ToggleRotationFriction.Identifier) + openspace.bindKey("F1", actions.ToggleMainGui) + openspace.bindKey("Shift+F1", actions.ToggleOverlays) - openspace.action.registerAction(ToggleZoomFriction) - openspace.bindKey("Shift+F", ToggleZoomFriction.Identifier) + openspace.bindKey("F2", actions.ToggleNativeUi) - openspace.action.registerAction(ToggleRollFriction) - openspace.bindKey("Ctrl+F", ToggleRollFriction.Identifier) + openspace.bindKey("Right", actions.NextDeltaStepInterpolate) + openspace.bindKey("Shift+Right", actions.NextDeltaStepImmediate) - openspace.action.registerAction(FadeToBlack) - openspace.bindKey("B", FadeToBlack.Identifier) + openspace.bindKey("Left", actions.PreviousDeltaStepInterpolate) + openspace.bindKey("Shift+Left", actions.PreviousDeltaStepImmediate) - openspace.action.registerAction(ToggleMainGui) - openspace.bindKey("TAB", ToggleMainGui.Identifier) + openspace.bindKey("Down", actions.RealTimeDeltaStepInterpolate) + openspace.bindKey("Shift+Down", actions.RealTimeDeltaStepImmediate) - openspace.action.registerAction(ToggleOverlays) - openspace.bindKey("Shift+TAB", ToggleOverlays.Identifier) - - openspace.action.registerAction(ToggleMasterRendering) - openspace.bindKey("Alt+R", ToggleMasterRendering.Identifier) - - openspace.action.registerAction(NextDeltaStepInterpolate) - openspace.bindKey("Right", NextDeltaStepInterpolate.Identifier) - - openspace.action.registerAction(NextDeltaStepImmediate) - openspace.bindKey("Shift+Right", NextDeltaStepImmediate.Identifier) - - openspace.action.registerAction(PreviousDeltaStepInterpolate) - openspace.bindKey("Left", PreviousDeltaStepInterpolate.Identifier) - - openspace.action.registerAction(PreviousDeltaStepImmediate) - openspace.bindKey("Shift+Left", PreviousDeltaStepImmediate.Identifier) - - openspace.action.registerAction(RealTimeDeltaStepInterpolate) - openspace.bindKey("Down", RealTimeDeltaStepInterpolate.Identifier) - - openspace.action.registerAction(RealTimeDeltaStepImmediate) - openspace.bindKey("Shift+Down", RealTimeDeltaStepImmediate.Identifier) - - openspace.action.registerAction(DateToNowInterpolate) - openspace.bindKey("Up", DateToNowInterpolate.Identifier) - - openspace.action.registerAction(DateToNowImmediate) - openspace.bindKey("Shift+Up", DateToNowImmediate.Identifier) - - openspace.action.registerAction(ReloadGui) - openspace.bindKey("F5", ReloadGui.Identifier) + openspace.bindKey("F5", actions.ReloadGui) end) asset.onDeinitialize(function() - openspace.clearKey("F5") - openspace.action.removeAction(ReloadGui) + openspace.clearKey("F5") -- actions.ReloadGui - openspace.clearKey("Shift+Up") - openspace.action.removeAction(DateToNowImmediate) + openspace.clearKey("Shift+Down") -- actions.RealTimeDeltaStepImmediate + openspace.clearKey("Down") -- actions.RealTimeDeltaStepInterpolate - openspace.clearKey("Up") - openspace.action.removeAction(DateToNowInterpolate) + openspace.clearKey("Shift+Left") -- actions.PreviousDeltaStepImmediate + openspace.clearKey("Left") -- actions.PreviousDeltaStepInterpolate - openspace.clearKey("Shift+Down") - openspace.action.removeAction(RealTimeDeltaStepImmediate) + openspace.clearKey("Shift+Right") -- actions.NextDeltaStepImmediate + openspace.clearKey("Right") -- actions.NextDeltaStepInterpolate - openspace.clearKey("Down") - openspace.action.removeAction(RealTimeDeltaStepInterpolate) + openspace.clearKey("F2") -- actions.ToggleNativeUi - openspace.clearKey("Shift+Left") - openspace.action.removeAction(PreviousDeltaStepImmediate) + openspace.clearKey("Shift+F1") -- actions.ToggleOverlays + openspace.clearKey("F1") -- actions.ToggleMainGui - openspace.clearKey("Left") - openspace.action.removeAction(PreviousDeltaStepInterpolate) + openspace.clearKey("B") -- actions.FadeToBlack - openspace.clearKey("Shift+Right") - openspace.action.removeAction(NextDeltaStepImmediate) + openspace.clearKey("Ctrl+F") -- actions.ToggleRollFriction + openspace.clearKey("Shift+F") -- actions.ToggleZoomFriction + openspace.clearKey("F") -- actions.ToggleRotationFriction - openspace.clearKey("Right") - openspace.action.removeAction(NextDeltaStepInterpolate) + openspace.clearKey("Shift+SPACE") -- actions.TogglePauseImmediate + openspace.clearKey("SPACE") -- actions.TogglePauseInterpolated - openspace.clearKey("Alt+R") - openspace.action.removeAction(ToggleMasterRendering) + openspace.clearKey("F12") -- actions.TakeScreenshot + openspace.clearKey("PRINT_SCREEN") -- actions.TakeScreenshot - openspace.clearKey("Shift+TAB") - openspace.action.removeAction(ToggleOverlays) - - openspace.clearKey("TAB") - openspace.action.removeAction(ToggleMainGui) - - openspace.clearKey("B") - openspace.action.removeAction(FadeToBlack) - - openspace.clearKey("Ctrl+F") - openspace.action.removeAction(ToggleRollFriction) - - openspace.clearKey("Shift+F") - openspace.action.removeAction(ToggleZoomFriction) - - openspace.clearKey("F") - openspace.action.removeAction(ToggleRotationFriction) - - openspace.clearKey("Shift+SPACE") - openspace.action.removeAction(TogglePauseImmediate) - - openspace.clearKey("SPACE") - openspace.action.removeAction(TogglePauseInterpolated) - - openspace.clearKey("F12") - openspace.clearKey("PRINT_SCREEN") - openspace.action.removeAction(TakeScreenshot) - - openspace.clearKey("ESC") - openspace.action.removeAction(ToggleShutdown) - - openspace.clearKey("F1") - openspace.action.removeAction(ToggleNativeUi) + openspace.clearKey("Ctrl+Q") -- actions.ToggleShutdown end) + + + +asset.meta = { + Name = "Default Keybindings", + Description ="Asset with default key bindings that are useful for all profiles", + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/events/toggle_sun.asset b/data/assets/events/toggle_sun.asset index 5da2652bd7..eca746134f 100644 --- a/data/assets/events/toggle_sun.asset +++ b/data/assets/events/toggle_sun.asset @@ -3,7 +3,8 @@ local ToggleSun = { Name = "Toggle Sun", Command = [[ if not is_declared("args") then - openspace.printError("Cannot execute 'os.ToggleSun' manually") + openspace.toggleFade("Scene.Sun.Renderable") + openspace.toggleFade("Scene.SunGlare.Renderable") return end diff --git a/data/assets/examples/dashboarditem/dashboarditemangle/angle_three-nodes.asset b/data/assets/examples/dashboarditem/dashboarditemangle/angle_three-nodes.asset new file mode 100644 index 0000000000..726dec459a --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemangle/angle_three-nodes.asset @@ -0,0 +1,61 @@ +-- Three nodes +-- This example adds three invisible scene graph nodes and then shows the angle between +-- those three nodes. + +local Node1 = { + Identifier = "DashboardItemAngle_Example_ThreeNodes_Node1", + GUI = { + Name = "DashboardItemAngle - Three Nodes (Node 1)" + } +} + +local Node2 = { + Identifier = "DashboardItemAngle_Example_ThreeNodes_Node2", + Transform = { + Translation = { + Type = "StaticTranslation", + Position = { 2.0, 1.0, 0.0 } + } + }, + GUI = { + Name = "DashboardItemAngle - Three Nodes (Node 2)" + } +} + +local Node3 = { + Identifier = "DashboardItemAngle_Example_ThreeNodes_Node3", + Transform = { + Translation = { + Type = "StaticTranslation", + Position = { -2.0, 1.0, 0.0 } + } + }, + GUI = { + Name = "DashboardItemAngle - Three Nodes (Node 3)" + } +} + +local Item = { + Identifier = "DashboardItemAngle_Example_ThreeNodes", + Type = "DashboardItemAngle", + SourceType = "Node", + SourceNodeIdentifier = Node1.Identifier, + ReferenceType = "Node", + ReferenceNodeIdentifier = Node2.Identifier, + DestinationType = "Node", + DestinationNodeIdentifier = Node3.Identifier +} + +asset.onInitialize(function() + openspace.addSceneGraphNode(Node1) + openspace.addSceneGraphNode(Node2) + openspace.addSceneGraphNode(Node3) + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) + openspace.removeSceneGraphNode(Node3) + openspace.removeSceneGraphNode(Node2) + openspace.removeSceneGraphNode(Node1) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditemangle/angle_two-nodes-camera.asset b/data/assets/examples/dashboarditem/dashboarditemangle/angle_two-nodes-camera.asset new file mode 100644 index 0000000000..267826b1e0 --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemangle/angle_two-nodes-camera.asset @@ -0,0 +1,45 @@ +-- Two nodes and camera +-- This example adds two invisible scene graph nodes and then shows the angle between the +-- camera and those two nodes. + +local Node1 = { + Identifier = "DashboardItemAngle_Example_TwoNodesCamera_Node1", + GUI = { + Name = "DashboardItemAngle - Two Nodes & Camera (Node 1)" + } +} + +local Node2 = { + Identifier = "DashboardItemAngle_Example_TwoNodesCamera_Node2", + Transform = { + Translation = { + Type = "StaticTranslation", + Position = { 20.0, 1.0, 0.0 } + } + }, + GUI = { + Name = "DashboardItemAngle - Two Nodes & Camera (Node 2)" + } +} + +local Item = { + Identifier = "DashboardItemAngle_Example_TwoNodesCamera", + Type = "DashboardItemAngle", + SourceType = "Camera", + ReferenceType = "Node", + ReferenceNodeIdentifier = Node1.Identifier, + DestinationType = "Node", + DestinationNodeIdentifier = Node2.Identifier +} + +asset.onInitialize(function() + openspace.addSceneGraphNode(Node1) + openspace.addSceneGraphNode(Node2) + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) + openspace.removeSceneGraphNode(Node2) + openspace.removeSceneGraphNode(Node1) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditemangle/angle_two-nodes-focus.asset b/data/assets/examples/dashboarditem/dashboarditemangle/angle_two-nodes-focus.asset new file mode 100644 index 0000000000..1bc93c50eb --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemangle/angle_two-nodes-focus.asset @@ -0,0 +1,45 @@ +-- Two nodes and focus +-- This example adds two invisible scene graph nodes and then shows the angle between the +-- current focus node and those two nodes. + +local Node1 = { + Identifier = "DashboardItemAngle_Example_TwoNodesFocus_Node1", + GUI = { + Name = "DashboardItemAngle - Two Nodes & Focus (Node 1)" + } +} + +local Node2 = { + Identifier = "DashboardItemAngle_Example_TwoNodesFocus_Node2", + Transform = { + Translation = { + Type = "StaticTranslation", + Position = { 20.0, 1.0, 0.0 } + } + }, + GUI = { + Name = "DashboardItemAngle - Two Nodes & Focus (Node 2)" + } +} + +local Item = { + Identifier = "DashboardItemAngle_Example_TwoNodesFocus", + Type = "DashboardItemAngle", + SourceType = "Focus", + ReferenceType = "Node", + ReferenceNodeIdentifier = Node1.Identifier, + DestinationType = "Node", + DestinationNodeIdentifier = Node2.Identifier +} + +asset.onInitialize(function() + openspace.addSceneGraphNode(Node1) + openspace.addSceneGraphNode(Node2) + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) + openspace.removeSceneGraphNode(Node2) + openspace.removeSceneGraphNode(Node1) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditemdate/date.asset b/data/assets/examples/dashboarditem/dashboarditemdate/date.asset new file mode 100644 index 0000000000..20e8dfef51 --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemdate/date.asset @@ -0,0 +1,15 @@ +-- Basic +-- This example adds a new DashboardItem that shows the current in-game simulation date. + +local Item = { + Identifier = "DashboardItemDate_Example", + Type = "DashboardItemDate" +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditemdate/date_day-of-year.asset b/data/assets/examples/dashboarditem/dashboarditemdate/date_day-of-year.asset new file mode 100644 index 0000000000..20640c7eaa --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemdate/date_day-of-year.asset @@ -0,0 +1,17 @@ +-- Day of Year +-- This example adds a new DashboardItem that shows the current in-game simulation date +-- showing the current year and the number of days that have passed in the year. + +local Item = { + Identifier = "DashboardItemDate_Example_DayOfYear", + Type = "DashboardItemDate", + TimeFormat = "YYYY DOY" +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditemdate/date_no-decoration.asset b/data/assets/examples/dashboarditem/dashboarditemdate/date_no-decoration.asset new file mode 100644 index 0000000000..9ef1348dff --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemdate/date_no-decoration.asset @@ -0,0 +1,17 @@ +-- No Decorations +-- This example adds a new DashboardItem that shows the current in-game simulation date +-- without any additional text surrounding the current date + +local Item = { + Identifier = "DashboardItemDate_Example_NoDecoration", + Type = "DashboardItemDate", + FormatString = "{}" +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditemdate/date_timezone.asset b/data/assets/examples/dashboarditem/dashboarditemdate/date_timezone.asset new file mode 100644 index 0000000000..e534124471 --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemdate/date_timezone.asset @@ -0,0 +1,17 @@ +-- Timezone +-- This example adds a new DashboardItem that shows the current in-game simulation date +-- with a timezone of UTC-7 (=PDT) + +local Item = { + Identifier = "DashboardItemDate_Example_Timezone", + Type = "DashboardItemDate", + TimeFormat = "YYYY MON DD HR:MN:SC.### PDT ::UTC-7" +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditemdate/date_year-month-day.asset b/data/assets/examples/dashboarditem/dashboarditemdate/date_year-month-day.asset new file mode 100644 index 0000000000..90af7135b2 --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemdate/date_year-month-day.asset @@ -0,0 +1,17 @@ +-- Year Month Day +-- This example adds a new DashboardItem that shows the current in-game simulation date +-- with a resolution of days. + +local Item = { + Identifier = "DashboardItemDate_Example_YearMonthDay", + Type = "DashboardItemDate", + TimeFormat = "YYYY MON DD" +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditemdistance/distance_node-camera.asset b/data/assets/examples/dashboarditem/dashboarditemdistance/distance_node-camera.asset new file mode 100644 index 0000000000..c6b2d5f8e9 --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemdistance/distance_node-camera.asset @@ -0,0 +1,28 @@ +-- Node-Camera +-- This example adds an invisible node and a dashboard item that shows the distance +-- between this node and the current focus node. + +local Node = { + Identifier = "DashboardItemDistance_Example_NodeCamera_Node", + GUI = { + Name = "DashboardItemDistance - Node-Camera" + } +} + +local Item = { + Identifier = "DashboardItemDistance_Example_NodeCamera", + Type = "DashboardItemDistance", + SourceType = "Node", + SourceNodeIdentifier = Node.Identifier, + DestinationType = "Camera" +} + +asset.onInitialize(function() + openspace.addSceneGraphNode(Node) + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) + openspace.removeSceneGraphNode(Node) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditemdistance/distance_node-focus.asset b/data/assets/examples/dashboarditem/dashboarditemdistance/distance_node-focus.asset new file mode 100644 index 0000000000..c62552dc9a --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemdistance/distance_node-focus.asset @@ -0,0 +1,28 @@ +-- Node-Focus +-- This example adds an invisible node and a dashboard item that shows the distance +-- between this node and the current focus node. + +local Node = { + Identifier = "DashboardItemDistance_Example_NodeFocus_Node", + GUI = { + Name = "DashboardItemDistance - Node-Focus" + } +} + +local Item = { + Identifier = "DashboardItemDistance_Example_NodeFocus", + Type = "DashboardItemDistance", + SourceType = "Node", + SourceNodeIdentifier = Node.Identifier, + DestinationType = "Focus" +} + +asset.onInitialize(function() + openspace.addSceneGraphNode(Node) + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) + openspace.removeSceneGraphNode(Node1) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditemdistance/distance_node-node.asset b/data/assets/examples/dashboarditem/dashboarditemdistance/distance_node-node.asset new file mode 100644 index 0000000000..bb686efe2a --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemdistance/distance_node-node.asset @@ -0,0 +1,44 @@ +-- Node-Node +-- This example adds two invisible nodes and a dashboard item that shows the distance +-- between those two nodes. + +local Node1 = { + Identifier = "DashboardItemDistance_Example_NodeNode_Node1", + GUI = { + Name = "DashboardItemDistance - Node-Node (Node 1)" + } +} + +local Node2 = { + Identifier = "DashboardItemDistance_Example_NodeNode_Node2", + Transform = { + Translation = { + Type = "StaticTranslation", + Position = { 2.0, 0.0, 0.0 } + } + }, + GUI = { + Name = "DashboardItemDistance - Node-Node (Node 2)" + } +} + +local Item = { + Identifier = "DashboardItemDistance_Example_NodeNode", + Type = "DashboardItemDistance", + SourceType = "Node", + SourceNodeIdentifier = Node1.Identifier, + DestinationType = "Node", + DestinationNodeIdentifier = Node2.Identifier +} + +asset.onInitialize(function() + openspace.addSceneGraphNode(Node1) + openspace.addSceneGraphNode(Node2) + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) + openspace.removeSceneGraphNode(Node2) + openspace.removeSceneGraphNode(Node1) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditemdistance/distance_nodesurface-camera.asset b/data/assets/examples/dashboarditem/dashboarditemdistance/distance_nodesurface-camera.asset new file mode 100644 index 0000000000..32cdf4894c --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemdistance/distance_nodesurface-camera.asset @@ -0,0 +1,29 @@ +-- NodeSurface-Camera +-- This example adds two invisible nodes and a dashboard item that shows the distance +-- between those two nodes + +local Node = { + Identifier = "DashboardItemDistance_Example_NodeSurfaceCamera_Node", + BoundingSphere = 200.0, + GUI = { + Name = "DashboardItemDistance - NodeSurface-Camera" + } +} + +local Item = { + Identifier = "DashboardItemDistance_Example_NodeSurfaceCamera", + Type = "DashboardItemDistance", + SourceType = "Node Surface", + SourceNodeIdentifier = Node.Identifier, + DestinationType = "Camera" +} + +asset.onInitialize(function() + openspace.addSceneGraphNode(Node) + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) + openspace.removeSceneGraphNode(Node) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditemelapsedtime/elapsed.asset b/data/assets/examples/dashboarditem/dashboarditemelapsedtime/elapsed.asset new file mode 100644 index 0000000000..8c02355f0b --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemelapsedtime/elapsed.asset @@ -0,0 +1,17 @@ +-- Basic +-- This example adds a dashboard item that shows the remaining time or the elapsed time +-- since midday 2000 JAN 01. + +local Item = { + Identifier = "DashboardItemElapsedTime_Example", + Type = "DashboardItemElapsedTime", + ReferenceTime = "2000 JAN 01 12:00:00" +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditemelapsedtime/elapsed_fixed-time.asset b/data/assets/examples/dashboarditem/dashboarditemelapsedtime/elapsed_fixed-time.asset new file mode 100644 index 0000000000..2e72405977 --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemelapsedtime/elapsed_fixed-time.asset @@ -0,0 +1,18 @@ +-- Fixed Time +-- This example adds a dashboard item that shows the remaining time or the elapsed time +-- since 2000 JAN 01 but ignoring any unit smaller than days. + +local Item = { + Identifier = "DashboardItemElapsedTime_Example_FixedTime", + Type = "DashboardItemElapsedTime", + ReferenceTime = "2000 JAN 01 12:00:00", + LowestTimeUnit = "Day" +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditemelapsedtime/elapsed_no-decoration.asset b/data/assets/examples/dashboarditem/dashboarditemelapsedtime/elapsed_no-decoration.asset new file mode 100644 index 0000000000..78b4730eea --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemelapsedtime/elapsed_no-decoration.asset @@ -0,0 +1,19 @@ +-- No Decorations +-- This example adds a dashboard item that shows the remaining time or the elapsed time +-- since midday 2000 JAN 01 without any additional text decoration and only printing the +-- remaining time. + +local Item = { + Identifier = "DashboardItemElapsedTime_Example_NoDecorations", + Type = "DashboardItemElapsedTime", + ReferenceTime = "2000 JAN 01 12:00:00", + FormatString = "{}" +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditemframerate/framerate.asset b/data/assets/examples/dashboarditem/dashboarditemframerate/framerate.asset new file mode 100644 index 0000000000..9cafcf215a --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemframerate/framerate.asset @@ -0,0 +1,16 @@ +-- Basic +-- This example adds a dashboard item that shows the average number of frames per second, +-- which is the default value for the frame time type setting. + +local Item = { + Identifier = "DashboardItemFramerate_Example", + Type = "DashboardItemFramerate" +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditemframerate/framerate_deltatime.asset b/data/assets/examples/dashboarditem/dashboarditemframerate/framerate_deltatime.asset new file mode 100644 index 0000000000..9b10d68970 --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemframerate/framerate_deltatime.asset @@ -0,0 +1,17 @@ +-- Delta Time +-- This example adds a dashboard item that shows the frame rate of the last frame in +-- milliseconds. + +local Item = { + Identifier = "DashboardItemFramerate_Example_DeltaTime", + Type = "DashboardItemFramerate", + FrametimeType = "Deltatime" +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditemglobelocation/globelocation.asset b/data/assets/examples/dashboarditem/dashboarditemglobelocation/globelocation.asset new file mode 100644 index 0000000000..bae123c1d1 --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemglobelocation/globelocation.asset @@ -0,0 +1,16 @@ +-- Basic +-- This example adds a dashboard item that shows the position of the camera relative to +-- the focus node, if that focus node is a globe. + +local Item = { + Identifier = "DashboardItemGlobeLocation_Example", + Type = "DashboardItemGlobeLocation" +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditemglobelocation/globelocation_dms.asset b/data/assets/examples/dashboarditem/dashboarditemglobelocation/globelocation_dms.asset new file mode 100644 index 0000000000..bd7d5cec2a --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemglobelocation/globelocation_dms.asset @@ -0,0 +1,18 @@ +-- Degree/Minute/Seconds +-- This example adds a dashboard item that shows the position of the camera relative to +-- the focus node, if that focus node is a globe. The longitude and latitude of the camera +-- is provided in the sexagesimal system (degrees, minutes, seconds). + +local Item = { + Identifier = "DashboardItemGlobeLocation_Example", + Type = "DashboardItemGlobeLocation", + DisplayFormat = "DegreeMinuteSeconds" +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditeminputstate/inputstate.asset b/data/assets/examples/dashboarditem/dashboarditeminputstate/inputstate.asset new file mode 100644 index 0000000000..27161f0757 --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditeminputstate/inputstate.asset @@ -0,0 +1,16 @@ +-- Basic +-- This example adds a dashboard item that shows the input state of the mouse, keyboard, +-- and joystick input devices. + +local Item = { + Identifier = "DashboardItemInputState_Example", + Type = "DashboardItemInputState" +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditeminputstate/inputstate_mouseonly.asset b/data/assets/examples/dashboarditem/dashboarditeminputstate/inputstate_mouseonly.asset new file mode 100644 index 0000000000..c66b3d2e97 --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditeminputstate/inputstate_mouseonly.asset @@ -0,0 +1,17 @@ +-- Mouse Only +-- This example adds a dashboard item that only shows the input state of the mouse inputs. + +local Item = { + Identifier = "DashboardItemInputState_Example_MouseOnly", + Type = "DashboardItemInputState", + ShowKeyboard = false, + ShowJoystick = false +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditeminputstate/inputstate_onlydisabled.asset b/data/assets/examples/dashboarditem/dashboarditeminputstate/inputstate_onlydisabled.asset new file mode 100644 index 0000000000..a341084be0 --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditeminputstate/inputstate_onlydisabled.asset @@ -0,0 +1,17 @@ +-- Only disabled +-- This example adds a dashboard item that shows the input state of the mouse, keyboard, +-- and joystick input devices but only when they are disabled. + +local Item = { + Identifier = "DashboardItemInputState_Example_OnlyDisabled", + Type = "DashboardItemInputState", + ShowWhenDisabled = true +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditemmission/mission.asset b/data/assets/examples/dashboarditem/dashboarditemmission/mission.asset new file mode 100644 index 0000000000..7f8886420a --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemmission/mission.asset @@ -0,0 +1,16 @@ +-- Basic +-- This example adds a dashboard item that shows the status of the currently active +-- mission. + +local Item = { + Identifier = "DashboardItemMission_Example", + Type = "DashboardItemMission" +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditemparallelconnection/parallelconnection.asset b/data/assets/examples/dashboarditem/dashboarditemparallelconnection/parallelconnection.asset new file mode 100644 index 0000000000..4c153674b8 --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemparallelconnection/parallelconnection.asset @@ -0,0 +1,15 @@ +-- Basic +-- This example adds a dashboard item that shows the status of the parallel connection. + +local Item = { + Identifier = "DashboardItemParallelConnection_Example", + Type = "DashboardItemParallelConnection" +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditempropertyvalue/propertyvalue_bool.asset b/data/assets/examples/dashboarditem/dashboarditempropertyvalue/propertyvalue_bool.asset new file mode 100644 index 0000000000..ba251345ba --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditempropertyvalue/propertyvalue_bool.asset @@ -0,0 +1,17 @@ +-- Bool +-- This example adds a dashboard item that shows the state of a boolean property. + +local Item = { + Identifier = "DashboardItemPropertyValue_Example_Bool", + Type = "DashboardItemPropertyValue", + URI = "NavigationHandler.OrbitalNavigator.Friction.RotationalFriction", + DisplayString = "Rotational Friction is: {}" +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditempropertyvalue/propertyvalue_float.asset b/data/assets/examples/dashboarditem/dashboarditempropertyvalue/propertyvalue_float.asset new file mode 100644 index 0000000000..7390c7801f --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditempropertyvalue/propertyvalue_float.asset @@ -0,0 +1,18 @@ +-- Float +-- This example adds a dashboard item that shows the state of a floating point value +-- property. + +local Item = { + Identifier = "DashboardItemPropertyValue_Example_Float", + Type = "DashboardItemPropertyValue", + URI = "RenderEngine.Gamma", + DisplayString = "Gamma Correction: {}" +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditempropertyvalue/propertyvalue_int.asset b/data/assets/examples/dashboarditem/dashboarditempropertyvalue/propertyvalue_int.asset new file mode 100644 index 0000000000..dd220cb847 --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditempropertyvalue/propertyvalue_int.asset @@ -0,0 +1,18 @@ +-- Int +-- This example adds a dashboard item that shows the state of a integer point value +-- property. + +local Item = { + Identifier = "DashboardItemPropertyValue_Example_Int", + Type = "DashboardItemPropertyValue", + URI = "LuaConsole.HistoryLength", + DisplayString = "Lua Console History Length: {}" +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditempropertyvalue/propertyvalue_vec3.asset b/data/assets/examples/dashboarditem/dashboarditempropertyvalue/propertyvalue_vec3.asset new file mode 100644 index 0000000000..680d30b5f3 --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditempropertyvalue/propertyvalue_vec3.asset @@ -0,0 +1,17 @@ +-- Vec3 +-- This example adds a dashboard item that shows the state of a 3-vector value property. + +local Item = { + Identifier = "DashboardItemPropertyValue_Example_Vec3", + Type = "DashboardItemPropertyValue", + URI = "RenderEngine.GlobalRotation", + DisplayString = "Global Rotation: ({}, {}, {})" +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditempropertyvalue/propertyvalue_vec4.asset b/data/assets/examples/dashboarditem/dashboarditempropertyvalue/propertyvalue_vec4.asset new file mode 100644 index 0000000000..4b4d8caf55 --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditempropertyvalue/propertyvalue_vec4.asset @@ -0,0 +1,17 @@ +-- Vec4 +-- This example adds a dashboard item that shows the state of a 4-vector value property. + +local Item = { + Identifier = "DashboardItemPropertyValue_Example_Vec4", + Type = "DashboardItemPropertyValue", + URI = "RenderEngine.EnabledFontColor", + DisplayString = "Font Color (enabled): ({}, {}, {}, {})" +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditemsimulationincrement/simulationincrement.asset b/data/assets/examples/dashboarditem/dashboarditemsimulationincrement/simulationincrement.asset new file mode 100644 index 0000000000..5f88f68d7e --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemsimulationincrement/simulationincrement.asset @@ -0,0 +1,15 @@ +-- Basic +-- This example adds a dashboard item that shows the current simulation increment. + +local Item = { + Identifier = "DashboardItemSimulationIncrement_Example", + Type = "DashboardItemSimulationIncrement" +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditemsimulationincrement/simulationincrement_nanoseconds.asset b/data/assets/examples/dashboarditem/dashboarditemsimulationincrement/simulationincrement_nanoseconds.asset new file mode 100644 index 0000000000..2404a14541 --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemsimulationincrement/simulationincrement_nanoseconds.asset @@ -0,0 +1,17 @@ +-- Nanoseconds +-- This example adds a dashboard item that shows the current simulation increment always +-- expressed in nanoseconds. + +local Item = { + Identifier = "DashboardItemSimulationIncrement_Example_NoDecoration", + Type = "DashboardItemSimulationIncrement", + RequestedUnit = "Nanosecond" +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditemsimulationincrement/simulationincrement_no-decoration.asset b/data/assets/examples/dashboarditem/dashboarditemsimulationincrement/simulationincrement_no-decoration.asset new file mode 100644 index 0000000000..196061b350 --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemsimulationincrement/simulationincrement_no-decoration.asset @@ -0,0 +1,22 @@ +-- No Decoration +-- This example adds a dashboard item that shows the current simulation increment without +-- any textual decorations. This example also shows how to ignore the first two parameters +-- the `TransitionFormat` format string. Both the `TransitionFormat` and the +-- `RegularFormat` string replacement markers allow the setting of numbers to determine +-- which argument should be placed in here. The `TransitionFormat` in this example omits +-- the numbers 0 and 1, thus ignoring the first two arguments to the string. + +local Item = { + Identifier = "DashboardItemSimulationIncrement_Example_NoDecoration", + Type = "DashboardItemSimulationIncrement", + TransitionFormat = "{3:.1f} {4:s} / second{2:s}", + RegularFormat = "{:.1f} {:s} / second{:s}" +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditemspacing/spacing.asset b/data/assets/examples/dashboarditem/dashboarditemspacing/spacing.asset new file mode 100644 index 0000000000..a4c3360111 --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemspacing/spacing.asset @@ -0,0 +1,16 @@ +-- Basic +-- This example adds a dashboard item that adds a spacing to the dashboard. This example +-- will not show anything by itself. + +local Item = { + Identifier = "DashboardItemSpacing_Example", + Type = "DashboardItemSpacing" +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditemtimevaryingtext/data/dummydata.json b/data/assets/examples/dashboarditem/dashboarditemtimevaryingtext/data/dummydata.json new file mode 100644 index 0000000000..a655d1f0de --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemtimevaryingtext/data/dummydata.json @@ -0,0 +1,9 @@ +{ + "data": [ + [ "2024-05-10T00:00:00Z", 2.33 ], + [ "2024-05-10T03:00:00Z", 3 ], + [ "2024-05-10T06:00:00Z", 3 ], + [ "2024-05-10T09:00:00Z", 2.67 ], + [ "2024-05-10T12:00:00Z", 2.33 ] + ] +} diff --git a/data/assets/examples/dashboarditem/dashboarditemtimevaryingtext/data/dummydata_mixed.json b/data/assets/examples/dashboarditem/dashboarditemtimevaryingtext/data/dummydata_mixed.json new file mode 100644 index 0000000000..9e4734c38e --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemtimevaryingtext/data/dummydata_mixed.json @@ -0,0 +1,10 @@ +{ + "data": [ + [ "2024-05-10T00:00:00Z", 2.33 ], + [ "2024-05-10T03:00:00Z", true ], + [ "2024-05-10T06:00:00Z", "Test string" ], + [ "2024-05-10T09:00:00Z", { "a": 1.0, "b": 2.0 } ], + [ "2024-05-10T12:00:00Z", [ 1.0, 2.0, 3.0 ] ], + [ "2024-05-10T15:00:00Z", 3 ] + ] +} diff --git a/data/assets/examples/dashboarditem/dashboarditemtimevaryingtext/timevaryingtext.asset b/data/assets/examples/dashboarditem/dashboarditemtimevaryingtext/timevaryingtext.asset new file mode 100644 index 0000000000..48230275c8 --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemtimevaryingtext/timevaryingtext.asset @@ -0,0 +1,16 @@ +-- Basic +-- This example shows how to create a time-varying text dashboard item. + +local Item = { + Type = "DashboardItemTimeVaryingText", + Identifier = "DashboardItemTimeVaryingText_Example", + DataFile = asset.resource("data/dummydata.json"), +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditemtimevaryingtext/timevaryingtext_mixed.asset b/data/assets/examples/dashboarditem/dashboarditemtimevaryingtext/timevaryingtext_mixed.asset new file mode 100644 index 0000000000..f7409eae41 --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemtimevaryingtext/timevaryingtext_mixed.asset @@ -0,0 +1,17 @@ +-- Mixed +-- This example shows how to create a time-varying text dashboard item that is using a +-- mixed type of data entries in the `DataFile`. + +local Item = { + Type = "DashboardItemTimeVaryingText", + Identifier = "DashboardItemTimeVaryingText_Example_Mixed", + DataFile = asset.resource("data/dummydata_mixed.json"), +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditemtimevaryingtext/timevaryingtext_styled.asset b/data/assets/examples/dashboarditem/dashboarditemtimevaryingtext/timevaryingtext_styled.asset new file mode 100644 index 0000000000..54b10c23f5 --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemtimevaryingtext/timevaryingtext_styled.asset @@ -0,0 +1,19 @@ +-- Styled +-- This example shows how to create a time-varying text dashboard item. +-- It has a custom font size and text before the time varying text. + +local Item = { + Type = "DashboardItemTimeVaryingText", + Identifier = "DashboardItemTimeVaryingText_Example_Styled", + DataFile = asset.resource("data/dummydata.json"), + FormatString = "Observed KP index: {}", + FontSize = 40 +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditemvelocity/velocity.asset b/data/assets/examples/dashboarditem/dashboarditemvelocity/velocity.asset new file mode 100644 index 0000000000..51d5d56c7d --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemvelocity/velocity.asset @@ -0,0 +1,15 @@ +-- Basic +-- This example adds a dashboard item that shows the speed of the camera. + +local Item = { + Identifier = "DashboardItemVelocity_Example", + Type = "DashboardItemVelocity" +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditem/dashboarditemvelocity/velocity_nauticalmiles.asset b/data/assets/examples/dashboarditem/dashboarditemvelocity/velocity_nauticalmiles.asset new file mode 100644 index 0000000000..c7f85bf1a9 --- /dev/null +++ b/data/assets/examples/dashboarditem/dashboarditemvelocity/velocity_nauticalmiles.asset @@ -0,0 +1,17 @@ +-- Nautical Miles +-- This example adds a dashboard item that shows the speed of the camera, but always +-- displayed in nautical miles per second (or knots). + +local Item = { + Identifier = "DashboardItemVelocity_Example_NauticalMiles", + Type = "DashboardItemVelocity", + RequestedUnit = "Nautical Mile" +} + +asset.onInitialize(function() + openspace.dashboard.addDashboardItem(Item) +end) + +asset.onDeinitialize(function() + openspace.dashboard.removeDashboardItem(Item) +end) diff --git a/data/assets/examples/dashboarditems.asset b/data/assets/examples/dashboarditems.asset deleted file mode 100644 index a072f0c44d..0000000000 --- a/data/assets/examples/dashboarditems.asset +++ /dev/null @@ -1,201 +0,0 @@ -asset.require("scene/solarsystem/planets/earth/earth") -asset.require("scene/solarsystem/planets/earth/moon/moon") - -local Angle = { - Type = "DashboardItemAngle", - Identifier = "Angle", - ReferenceType = "Node", - ReferenceNodeName = "Earth", - DestinationType = "Node", - DestinationNodeName = "Moon" -} - -local Date = { - Type = "DashboardItemDate", - Identifier = "Date" -} - -local SimulationIncrement = { - Type = "DashboardItemSimulationIncrement", - Identifier = "SimulationIncrement", - GuiName = "Simulation Increment" -} - -local Distance = { - Type = "DashboardItemDistance", - Identifier = "Distance" -} - -local Framerate = { - Type = "DashboardItemFramerate", - Identifier = "Framerate" -} - -local ParallelConnection = { - Type = "DashboardItemParallelConnection", - Identifier = "ParallelConnection", - GuiName = "Parallel Connection" -} - -local Mission = { - Type = "DashboardItemMission", - Identifier = "Mission" -} - -local PropertyValue = { - Type = "DashboardItemPropertyValue", - Identifier = "DashbaordItemPropertyValue", - URI = "Scene.Earth.Renderable.Enabled", - DisplayString = "Earth is enabled: {}" -} - -local PropertyValueFloat = { - Type = "DashboardItemPropertyValue", - Identifier = "DashbaordItemPropertyValue_Float", - URI = "Scene.Earth.Renderable.TargetLodScaleFactor", - DisplayString = "Earth LOD is {:.5f}" -} - -local PropertyValueDouble = { - Type = "DashboardItemPropertyValue", - Identifier = "DashbaordItemPropertyValue_Double", - URI = "NavigationHandler.PathNavigator.ArrivalDistanceFactor", - DisplayString = "Arrival Distance Factor is {:.8f}" -} - -local PropertyValueInt = { - Type = "DashboardItemPropertyValue", - Identifier = "DashbaordItemPropertyValue_Int", - URI = "LuaConsole.HistoryLength", - DisplayString = "History length is {}" -} - -local PropertyValueUInt = { - Type = "DashboardItemPropertyValue", - Identifier = "DashboardItemPropertyValue_UInt", - URI = "Modules.Globebrowsing.TileCacheSize", - DisplayString = "Tile Cache Size is {}" -} - -local PropertyValueDVec3 = { - Type = "DashboardItemPropertyValue", - Identifier = "DashboardItemPropertyValue_DVec3", - URI = "Scene.SolarSystemBarycenter.Transform.Transform", - DisplayString = "SSB Transform is: ({}, {}, {})" -} - -local PropertyValueIVec2 = { - Type = "DashboardItemPropertyValue", - Identifier = "DashboardItemPropertyValue_IVec2", - URI = "Scene.SolarSystemBarycenter.Renderable.ScreenSpacePosition", - DisplayString = "Random ScreenSpace Position: ({}, {})" -} - -local PropertyValueVec2 = { - Type = "DashboardItemPropertyValue", - Identifier = "DashboardItemPropertyValue_Vec2", - URI = "Scene.EarthAtmosphere.Renderable.AtmosphereDimmingSunsetAngle", - DisplayString = "Sunset Angle is ({}, {})" -} - -local PropertyValueVec3 = { - Type = "DashboardItemPropertyValue", - Identifier = "DashboardItemPropertyValue_Vec3", - URI = "RenderEngine.GlobalRotation", - DisplayString = "Global Rotation is ({}, {}, {})" -} - -local PropertyValueVec4 = { - Type = "DashboardItemPropertyValue", - Identifier = "DashboardItemPropertyValue_Vec4", - URI = "LuaConsole.BackgroundColor", - DisplayString = "Background Coolor is ({}, {}, {}, {})" -} - -local ElapsedTime = { - Type = "DashboardItemElapsedTime", - Identifier = "ElapsedTime", - ReferenceTime = "2022-10-12 12:00:00" -} - -local InputState = { - Type = "DashboardItemInputState", - Identifier = "InputState" -} - - -asset.onInitialize(function() - openspace.dashboard.addDashboardItem(Angle) - openspace.dashboard.addDashboardItem(Date) - openspace.dashboard.addDashboardItem(SimulationIncrement) - openspace.dashboard.addDashboardItem(Distance) - openspace.dashboard.addDashboardItem(Framerate) - openspace.dashboard.addDashboardItem(ParallelConnection) - openspace.dashboard.addDashboardItem(Mission) - openspace.dashboard.addDashboardItem(PropertyValue) - openspace.dashboard.addDashboardItem(PropertyValueFloat) - openspace.dashboard.addDashboardItem(PropertyValueDouble) - openspace.dashboard.addDashboardItem(PropertyValueInt) - openspace.dashboard.addDashboardItem(PropertyValueUInt) - openspace.dashboard.addDashboardItem(PropertyValueDVec3) - openspace.dashboard.addDashboardItem(PropertyValueIVec2) - openspace.dashboard.addDashboardItem(PropertyValueVec2) - openspace.dashboard.addDashboardItem(PropertyValueVec3) - openspace.dashboard.addDashboardItem(PropertyValueVec4) - openspace.dashboard.addDashboardItem(ElapsedTime) - openspace.dashboard.addDashboardItem(InputState) -end) - -asset.onDeinitialize(function() - openspace.dashboard.removeDashboardItem(InputState) - openspace.dashboard.removeDashboardItem(ElapsedTime) - openspace.dashboard.removeDashboardItem(PropertyValueVec4) - openspace.dashboard.removeDashboardItem(PropertyValueVec3) - openspace.dashboard.removeDashboardItem(PropertyValueVec2) - openspace.dashboard.removeDashboardItem(PropertyValueIVec2) - openspace.dashboard.removeDashboardItem(PropertyValueDVec3) - openspace.dashboard.removeDashboardItem(PropertyValueUInt) - openspace.dashboard.removeDashboardItem(PropertyValueInt) - openspace.dashboard.removeDashboardItem(PropertyValueDouble) - openspace.dashboard.removeDashboardItem(PropertyValueFloat) - openspace.dashboard.removeDashboardItem(PropertyValue) - openspace.dashboard.removeDashboardItem(Mission) - openspace.dashboard.removeDashboardItem(ParallelConnection) - openspace.dashboard.removeDashboardItem(Framerate) - openspace.dashboard.removeDashboardItem(Distance) - openspace.dashboard.removeDashboardItem(SimulationIncrement) - openspace.dashboard.removeDashboardItem(Date) - openspace.dashboard.removeDashboardItem(Angle) -end) - -asset.export(Angle) -asset.export(Date) -asset.export(SimulationIncrement) -asset.export(Distance) -asset.export(Framerate) -asset.export(ParallelConnection) -asset.export(Mission) -asset.export(PropertyValue) -asset.export(PropertyValueFloat) -asset.export(PropertyValueDouble) -asset.export(PropertyValueInt) -asset.export(PropertyValueUInt) -asset.export(PropertyValueDVec3) -asset.export(PropertyValueIVec2) -asset.export(PropertyValueVec2) -asset.export(PropertyValueVec3) -asset.export(PropertyValueVec4) -asset.export(ElapsedTime) -asset.export(InputState) - - - -asset.meta = { - Name = "Dashboard Items Example", - Description = [[Examples of different types of dashboard items. These are dynamic - information texts that will be shown over the rendering (per default in the top - left corner, on flat screens).]], - Author = "OpenSpace Team", - URL = "http://openspaceproject.com", - License = "MIT license" -} diff --git a/data/assets/examples/geojson/geojson_points_relative_texture_path.asset b/data/assets/examples/geojson/geojson_points_relative_texture_path.asset new file mode 100644 index 0000000000..0a020e2fd6 --- /dev/null +++ b/data/assets/examples/geojson/geojson_points_relative_texture_path.asset @@ -0,0 +1,51 @@ +local earth = asset.require("scene/solarsystem/planets/earth/earth") + + + +-- These two files are downloaded from the servers when the asset gets loaded. Specifying +-- these two URLs in this way will cause them to be downloaded into the same folder on the +-- harddisk. For this example this is important as the points-relative.geojson will ask +-- for the image.png in the same folder by specifying "./image.png" +local data = asset.resource({ + Name = "GeoJSON Example Relative Texture Path", + Type = "UrlSynchronization", + Identifier = "geojson_example_points_relative_path", + Url = { + "http://liu-se.cdn.openspaceproject.com/files/examples/geojson/points-relative.geojson", + "http://liu-se.cdn.openspaceproject.com/files/examples/geojson/image.png" + } +}) + + +local ExamplePoints = { + Identifier = "Points-Example-RelativeTexturePath", + File = data .. "points-relative.geojson", + HeightOffset = 20000.0, + DefaultProperties = { + PointSize = 10.0 + }, + Name = "Example Points (Relative Texture Path)" +} + + +asset.onInitialize(function() + openspace.globebrowsing.addGeoJson(earth.Earth.Identifier, ExamplePoints) +end) + +asset.onDeinitialize(function() + openspace.globebrowsing.deleteGeoJson(earth.Earth.Identifier, ExamplePoints) +end) + +asset.export(ExamplePoints) + + + +asset.meta = { + Name = "GeoJson Example - Points (Relative Texture Path)", + Description = [[GeoJson example asset with points that are facing the camera + (default). This example is using a relative path to specify the location of the image + that is to be used.]], + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/examples/renderable/renderableboxgrid/boxgrid.asset b/data/assets/examples/renderable/renderableboxgrid/boxgrid.asset index c73dcf4c32..bd9547cc1a 100644 --- a/data/assets/examples/renderable/renderableboxgrid/boxgrid.asset +++ b/data/assets/examples/renderable/renderableboxgrid/boxgrid.asset @@ -2,8 +2,8 @@ -- This example adds a box grid, which is a 3D box rendered using grid lines, to the -- scene. -- --- Per default, the box will be given a size of 1x1x1 meters, and here it is scaled up by a --- factor of 100. It will hence have a size of 100x100x100 meters. +-- Per default, the box will be given a size of 1x1x1 meters, and here it is scaled up by +-- a factor of 100. It will hence have a size of 100x100x100 meters. local Node = { Identifier = "RenderableBoxGrid_Example", diff --git a/data/assets/examples/renderable/renderableboxgrid/boxgrid_styled.asset b/data/assets/examples/renderable/renderableboxgrid/boxgrid_styled.asset index e2911244b4..e62ef22cb5 100644 --- a/data/assets/examples/renderable/renderableboxgrid/boxgrid_styled.asset +++ b/data/assets/examples/renderable/renderableboxgrid/boxgrid_styled.asset @@ -1,9 +1,18 @@ -- Styled -- This example creates a box grid where the grid lines are styled to have a specific -- color and line width. +-- +-- Per default, the box will be given a size of 1x1x1 meters, and here it is scaled up by +-- a factor of 100. It will hence have a size of 100x100x100 meters. local Node = { Identifier = "RenderableBoxGrid_Example_Styled", + Transform = { + Scale = { + Type = "StaticScale", + Scale = 100 + } + }, Renderable = { Type = "RenderableBoxGrid", LineWidth = 4.0, diff --git a/data/assets/examples/renderable/renderablecartesianaxes/cartesianaxes.asset b/data/assets/examples/renderable/renderablecartesianaxes/cartesianaxes.asset index 14f9f23159..74f5793a53 100644 --- a/data/assets/examples/renderable/renderablecartesianaxes/cartesianaxes.asset +++ b/data/assets/examples/renderable/renderablecartesianaxes/cartesianaxes.asset @@ -1,6 +1,6 @@ -- Basic --- This example creates a SceneGraphNode that only displays coordinate axes. The --- parent is not set which defaults to placing the axes at the center of the Sun. +-- This example creates a scene graph node that only displays coordinate axes. The parent +-- is not set which defaults to placing the axes at the center of the Sun. local Node = { Identifier = "RenderableCartesianAxes_Example", diff --git a/data/assets/examples/renderable/renderablecartesianaxes/cartesianaxes_parent.asset b/data/assets/examples/renderable/renderablecartesianaxes/cartesianaxes_parent.asset index 4dc7eb0dfd..67baebeffb 100644 --- a/data/assets/examples/renderable/renderablecartesianaxes/cartesianaxes_parent.asset +++ b/data/assets/examples/renderable/renderablecartesianaxes/cartesianaxes_parent.asset @@ -1,6 +1,6 @@ -- With Parent --- This example creates a SceneGraphNode that displays coordinate axes of the given parent --- node, in this case Earth. +-- This example creates a scene graph node that displays coordinate axes of the given +-- parent node, in this case Earth. local earth = asset.require("scene/solarsystem/planets/earth/earth") diff --git a/data/assets/examples/renderable/renderablenodearrow/nodearrow_appearance.asset b/data/assets/examples/renderable/renderablenodearrow/nodearrow_appearance.asset index 50eb794286..012c30b239 100644 --- a/data/assets/examples/renderable/renderablenodearrow/nodearrow_appearance.asset +++ b/data/assets/examples/renderable/renderablenodearrow/nodearrow_appearance.asset @@ -24,7 +24,9 @@ local Node = { -- the arrow ArrowHeadSize = 0.25, -- Set the arrow head width. A value of 1 makes it as wide as the body of the arrow - ArrowHeadWidthFactor = 1.0 + ArrowHeadWidthFactor = 1.0, + -- How wide should the arrow be (meters) + Width = 1000000.0 }, GUI = { Name = "RenderableNodeArrow - Custom Appearance (Colored & Inverted)", diff --git a/data/assets/examples/renderable/renderableplaneimagelocal/planeimagelocal.asset b/data/assets/examples/renderable/renderableplaneimagelocal/planeimagelocal.asset new file mode 100644 index 0000000000..13c4b57a2a --- /dev/null +++ b/data/assets/examples/renderable/renderableplaneimagelocal/planeimagelocal.asset @@ -0,0 +1,24 @@ +-- Basic +-- This example shows how to create a textured plane in 3D space, where the texture is +-- loaded from a local file on disk. + +local Node = { + Identifier = "RenderablePlaneImageLocal_Example", + Renderable = { + Type = "RenderablePlaneImageLocal", + Size = 3.0E11, + Texture = openspace.absPath("${DATA}/test2.jpg") + }, + GUI = { + Name = "RenderablePlaneImageLocal - Basic", + Path = "/Examples" + } +} + +asset.onInitialize(function() + openspace.addSceneGraphNode(Node) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(Node) +end) diff --git a/data/assets/examples/renderable/renderableplaneimagelocal/planeimagelocal_billboard.asset b/data/assets/examples/renderable/renderableplaneimagelocal/planeimagelocal_billboard.asset new file mode 100644 index 0000000000..890289fd8b --- /dev/null +++ b/data/assets/examples/renderable/renderableplaneimagelocal/planeimagelocal_billboard.asset @@ -0,0 +1,26 @@ +-- Billboard Image +-- This example shows how to create a textured plane in 3D space, where the texture is +-- loaded from a local file on disk and the plane is billboarded to always face the +-- camera. + +local Node = { + Identifier = "RenderablePlaneImageLocal_Example_Billboard", + Renderable = { + Type = "RenderablePlaneImageLocal", + Size = 3.0E11, + Texture = openspace.absPath("${DATA}/test2.jpg"), + Billboard = true + }, + GUI = { + Name = "RenderablePlaneImageLocal - Billboard", + Path = "/Examples" + } +} + +asset.onInitialize(function() + openspace.addSceneGraphNode(Node) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(Node) +end) diff --git a/data/assets/examples/renderable/renderableplaneimagelocal/planeimagelocal_scalebydistance.asset b/data/assets/examples/renderable/renderableplaneimagelocal/planeimagelocal_scalebydistance.asset new file mode 100644 index 0000000000..2b91d382f0 --- /dev/null +++ b/data/assets/examples/renderable/renderableplaneimagelocal/planeimagelocal_scalebydistance.asset @@ -0,0 +1,34 @@ +-- Scale by Distance to Camera +-- This example creates a textured plane that is scaled based on the distance to the +-- camera, so that it stays a constant size in screen space. The scale is limited so that +-- the plane does not become larger or smaller than a given max height and min height, in +-- meters. + +local earth = asset.require("scene/solarsystem/planets/earth/earth") + +local Node = { + Identifier = "RenderablePlaneImageLocal_Example_ScaleByDistance", + Renderable = { + Type = "RenderablePlaneImageLocal", + Size = 100000, + Texture = openspace.absPath("${DATA}/test2.jpg"), + DistanceScalingSettings = { + ScaleByDistance = true, + ApparentSizeMultiplier = 0.01, + ScaleByDistanceMaxHeight = 200000, + ScaleByDistanceMinHeight = 30000 + } + }, + GUI = { + Name = "RenderablePlaneImageLocal - ScaleByDistance", + Path = "/Examples" + } +} + +asset.onInitialize(function() + openspace.addSceneGraphNode(Node) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(Node) +end) diff --git a/data/assets/examples/renderable/renderableplaneimageonline/planeimageonline_billboarded.asset b/data/assets/examples/renderable/renderableplaneimageonline/planeimageonline_billboard.asset similarity index 77% rename from data/assets/examples/renderable/renderableplaneimageonline/planeimageonline_billboarded.asset rename to data/assets/examples/renderable/renderableplaneimageonline/planeimageonline_billboard.asset index e89d8eaad9..51b0016052 100644 --- a/data/assets/examples/renderable/renderableplaneimageonline/planeimageonline_billboarded.asset +++ b/data/assets/examples/renderable/renderableplaneimageonline/planeimageonline_billboard.asset @@ -1,18 +1,18 @@ --- Billboarded Image +-- Billboard Image -- This example shows how to create a textured plane in 3D space, where the texture is -- loaded from the internet though a web URL and the plane is billboarded to always -- face the camera. local Node = { - Identifier = "RenderablePlaneImageOnline_Example_Billboarded", + Identifier = "RenderablePlaneImageOnline_Example_Billboard", Renderable = { Type = "RenderablePlaneImageOnline", Size = 3.0E11, URL = "http://data.openspaceproject.com/examples/renderableplaneimageonline.jpg", - Billboarded = true + Billboard = true }, GUI = { - Name = "RenderablePlaneImageOnline - Billboarded", + Name = "RenderablePlaneImageOnline - Billboard", Path = "/Examples" } } diff --git a/data/assets/examples/renderable/renderablepointcloud/advanced/pointcloud_labels.asset b/data/assets/examples/renderable/renderablepointcloud/advanced/pointcloud_labels.asset index db3d4399a0..8cd505d6ef 100644 --- a/data/assets/examples/renderable/renderablepointcloud/advanced/pointcloud_labels.asset +++ b/data/assets/examples/renderable/renderablepointcloud/advanced/pointcloud_labels.asset @@ -29,7 +29,7 @@ local Node = { }, GUI = { Name = "RenderablePointCloud - Labels", - Path = "/Examples/Advanced" + Path = "/Examples/RenderablePointCloud/Advanced" } } @@ -66,7 +66,7 @@ local Node_LabelsFile = { } }, GUI = { - Name = "Labels - Custom File", + Name = "RenderablePointCloud - Labels Custom File", Path = "/Examples/RenderablePointCloud/Advanced", Description = [[Example of a point cloud with labels, created from a .label file]] } diff --git a/data/assets/examples/renderable/renderablepointcloud/advanced/pointcloud_multitextured.asset b/data/assets/examples/renderable/renderablepointcloud/advanced/pointcloud_multitextured.asset index 296a1d366c..c66eb3a5ba 100644 --- a/data/assets/examples/renderable/renderablepointcloud/advanced/pointcloud_multitextured.asset +++ b/data/assets/examples/renderable/renderablepointcloud/advanced/pointcloud_multitextured.asset @@ -60,13 +60,11 @@ local Node_Interpolated = { } -- Load data from a Speck file. This allows storing all data in one single file, including --- the texture mapping) Note that we disable this scene graph node per default here, as it --- shows the same information as the CSV version +-- the texture mapping). local Node_Speck = { Identifier = "RenderablePointCloud_Example_MultiTextured_Speck", Renderable = { Type = "RenderablePointCloud", - Enabled = false, -- When loading multi-texture information from a speck file, we do not need a -- DataMapping entry - all information is in the file File = asset.resource("../data/multitextured_speck/textures_points.speck"), diff --git a/data/assets/examples/renderable/renderablepointcloud/pointcloud_textured_facecameraposition.asset b/data/assets/examples/renderable/renderablepointcloud/pointcloud_textured_facecameraposition.asset index 9d950ecfa3..7e27735d60 100644 --- a/data/assets/examples/renderable/renderablepointcloud/pointcloud_textured_facecameraposition.asset +++ b/data/assets/examples/renderable/renderablepointcloud/pointcloud_textured_facecameraposition.asset @@ -9,13 +9,13 @@ -- See Textured example for more details. local Node = { - Identifier = "RenderablePointCloud_Example_FaceCameraPosition", + Identifier = "RenderablePointCloud_Example_Textured_FaceCameraPosition", Renderable = { Type = "RenderablePointCloud", File = asset.resource("data/dummydata.csv"), -- Change the orientation render option to face the camera position instead -- of its view direction - OrientationRenderOption = "Camera Position Normal", + Billboard = "Camera Position Normal", -- Add a texture so we can more easily see how the orientation is changed Texture = { File = openspace.absPath("${DATA}/test3.jpg") @@ -23,7 +23,7 @@ local Node = { UseAdditiveBlending = false }, GUI = { - Name = "RenderablePointCloud - Face Camera Position", + Name = "RenderablePointCloud - Textured Face Camera Position", Path = "/Examples" } } diff --git a/data/assets/examples/renderable/renderableswitch/switch.asset b/data/assets/examples/renderable/renderableswitch/switch.asset new file mode 100644 index 0000000000..b3fa31ed0c --- /dev/null +++ b/data/assets/examples/renderable/renderableswitch/switch.asset @@ -0,0 +1,36 @@ +-- Basic +-- This example shows how to create a renderable that switches between two textured planes +-- in 3D space, where one texture is loaded from a local file on disk and the other is +-- loaded from the internet though a web URL. +-- The switch is done based on the distance from the camera to the renderable. + +local Node = { + Identifier = "RenderableSwitch_Example", + Renderable = { + Type = "RenderableSwitch", + RenderableNear = { + Type = "RenderablePlaneImageLocal", + Size = 300000000000, + Texture = openspace.absPath("${DATA}/test.jpg") + }, + RenderableFar = { + Type = "RenderablePlaneImageOnline", + Size = 300000000000, + URL = "http://data.openspaceproject.com/examples/renderableplaneimageonline.jpg" + }, + DistanceThreshold = 2000000000000 + }, + GUI = { + Name = "RenderableSwitch - Basic", + Path = "/Examples" + } +} + +asset.onInitialize(function() + openspace.addSceneGraphNode(Node) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(Node) +end) + diff --git a/data/assets/examples/renderable/renderableswitch/switch_far.asset b/data/assets/examples/renderable/renderableswitch/switch_far.asset new file mode 100644 index 0000000000..2524b76e9e --- /dev/null +++ b/data/assets/examples/renderable/renderableswitch/switch_far.asset @@ -0,0 +1,30 @@ +-- Only Far Renderable +-- This example uses only shows a textured plane when the camera is further than the +-- specified distance from the object and shows nothing if the camera is closer than that +-- distance + +local Node = { + Identifier = "RenderableSwitch_Example-Far", + Renderable = { + Type = "RenderableSwitch", + RenderableFar = { + Type = "RenderablePlaneImageLocal", + Size = 300000000000, + Texture = openspace.absPath("${DATA}/test.jpg") + }, + DistanceThreshold = 3000000000000 + }, + GUI = { + Name = "RenderableSwitch - Far", + Path = "/Examples" + } +} + +asset.onInitialize(function() + openspace.addSceneGraphNode(Node) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(Node) +end) + diff --git a/data/assets/examples/renderable/renderableswitch/switch_near.asset b/data/assets/examples/renderable/renderableswitch/switch_near.asset new file mode 100644 index 0000000000..6100238ec8 --- /dev/null +++ b/data/assets/examples/renderable/renderableswitch/switch_near.asset @@ -0,0 +1,29 @@ +-- Only Near Renderable +-- This example uses only shows a textured plane when the camera is within the specified +-- distance from the object and shows nothing if the camera is further away. + +local Node = { + Identifier = "RenderableSwitch_Example-Near", + Renderable = { + Type = "RenderableSwitch", + RenderableNear = { + Type = "RenderablePlaneImageLocal", + Size = 300000000000, + Texture = openspace.absPath("${DATA}/test.jpg") + }, + DistanceThreshold = 2000000000000 + }, + GUI = { + Name = "RenderableSwitch - Near", + Path = "/Examples" + } +} + +asset.onInitialize(function() + openspace.addSceneGraphNode(Node) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(Node) +end) + diff --git a/data/assets/examples/rotation/fixedrotation/fixed.asset b/data/assets/examples/rotation/fixedrotation/fixed.asset new file mode 100644 index 0000000000..344ee24ed7 --- /dev/null +++ b/data/assets/examples/rotation/fixedrotation/fixed.asset @@ -0,0 +1,56 @@ +-- Basic +-- This asset creates a rotation that places coordinate axes close to a sphere with the +-- z axis pointing towards the sphere. The coordinate axes are translated away from the +-- sphere to make that orientation more obvious. +-- +-- Making the `YAxis` `{ 0.0, 1.0, 0.0 }` and actually using the orthogonal projection of +-- that direction means that the y axis of the new coordinate system will point in the +-- hemisphere in which the old y-axis was pointing, albeit being orthogonal to the other +-- specified axis. That axis is pointing towards the scene graph node holding the sphere. + +local Sphere = { + Identifier = "FixedRotation_Example_Sphere", + Transform = { + Translation = { + Type = "StaticTranslation", + Position = { 2.0, 1.5, 1.0 } + } + }, + Renderable = { + Type = "RenderableSphericalGrid" + }, + GUI = { + Name = "FixedRotation - Basic (Sphere)", + Path = "/Examples" + } +} + +local Node = { + Identifier = "FixedRotation_Example", + Transform = { + Rotation = { + Type = "FixedRotation", + Attached = "FixedRotation_Example", + YAxis = { 0.0, 1.0, 0.0 }, + YAxisOrthogonal = true, + ZAxis = "FixedRotation_Example_Sphere" + } + }, + Renderable = { + Type = "RenderableCartesianAxes" + }, + GUI = { + Name = "FixedRotation - Basic", + Path = "/Examples" + } +} + +asset.onInitialize(function() + openspace.addSceneGraphNode(Sphere) + openspace.addSceneGraphNode(Node) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(Node) + openspace.removeSceneGraphNode(Sphere) +end) diff --git a/data/assets/examples/rotation/fixedrotation/fixed_axis-mapping.asset b/data/assets/examples/rotation/fixedrotation/fixed_axis-mapping.asset new file mode 100644 index 0000000000..fdc3882d06 --- /dev/null +++ b/data/assets/examples/rotation/fixedrotation/fixed_axis-mapping.asset @@ -0,0 +1,33 @@ +-- Axis Mapping +-- This asset creates a rotation that shows coordinate axes in which the x and the y axes +-- are flipped. While this could also be achieved with a +-- [ConstantRotation](#base_transform_rotation_constant) class, this serves as an example +-- for more elaborate coordinate system mappings, such as converting to a coordinate +-- system with a known coordinate axes. + +local Node = { + Identifier = "FixedRotation_Example_Mapping", + Transform = { + Rotation = { + Type = "FixedRotation", + XAxis = { 0.0, 1.0, 0.0 }, + YAxis = { 1.0, 0.0, 0.0 }, + ZAxis = { 0.0, 0.0, 1.0 } + } + }, + Renderable = { + Type = "RenderableCartesianAxes" + }, + GUI = { + Name = "FixedRotation - Mapping", + Path = "/Examples" + } +} + +asset.onInitialize(function() + openspace.addSceneGraphNode(Node) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(Node) +end) diff --git a/data/assets/examples/rotation/fixedrotation/fixed_inverted.asset b/data/assets/examples/rotation/fixedrotation/fixed_inverted.asset new file mode 100644 index 0000000000..30f751d624 --- /dev/null +++ b/data/assets/examples/rotation/fixedrotation/fixed_inverted.asset @@ -0,0 +1,56 @@ +-- Inverted Axis +-- This asset creates a rotation that places coordinate axes close to a sphere with the z +-- axis pointing away from the sphere. The coordinate axes are translated away from the +-- sphere to make that orientation more obvious. +-- +-- Making the `YAxis` { 0.0, 1.0, 0.0 } and actually using the orthogonal projection of +-- that direction means that the y axis of the new coordinate system will point in the +-- hemisphere in which the old y-axis was pointing, albeit being orthogonal to the other +-- specified axis. That axis is pointing towards the scene graph node holding the sphere. +local Sphere = { + Identifier = "FixedRotation_Example_InvertedAxis_Sphere", + Transform = { + Translation = { + Type = "StaticTranslation", + Position = { 2.0, 1.5, 1.0 } + } + }, + Renderable = { + Type = "RenderableSphericalGrid" + }, + GUI = { + Name = "FixedRotation - Inverted Axis (Sphere)", + Path = "/Examples" + } +} + +local Node = { + Identifier = "FixedRotation_Example_InvertedAxis", + Transform = { + Rotation = { + Type = "FixedRotation", + Attached = "FixedRotation_Example_InvertedAxis", + YAxis = { 0.0, 1.0, 0.0 }, + YAxisOrthogonal = true, + ZAxis = Sphere.Identifier, + ZAxisInvert = true + } + }, + Renderable = { + Type = "RenderableCartesianAxes" + }, + GUI = { + Name = "FixedRotation - Inverted Axis", + Path = "/Examples" + } +} + +asset.onInitialize(function() + openspace.addSceneGraphNode(Sphere) + openspace.addSceneGraphNode(Node) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(Node) + openspace.removeSceneGraphNode(Sphere) +end) diff --git a/data/assets/examples/rotation/fixedrotation/fixed_moving-two-objects.asset b/data/assets/examples/rotation/fixedrotation/fixed_moving-two-objects.asset new file mode 100644 index 0000000000..2cccd5336b --- /dev/null +++ b/data/assets/examples/rotation/fixedrotation/fixed_moving-two-objects.asset @@ -0,0 +1,87 @@ +-- Rotation Following Two Moving Objects +-- This asset creates a rotation that places coordinate axes orbiting close to two spheres +-- with the y axis always pointing towards the first sphere and the z axis always pointing +-- towards the second sphere as the coordinate system moves around. The set of coordinate +-- axes are orbiting using a [KeplerTranslation](#space_transform_kepler) that provides a +-- configurable orbital motion. The use of the +-- [KeplerTranslation](#space_transform_kepler) in this example is arbitrary and the +-- FixedRotation does not depend on the use of that class. We use it in this example as we +-- want a moving object to show that the `FixedRotation` will always point at the object, +-- even as it is moving. +-- +-- Note that in this example the coordinate system will be skewed as, in general, it is +-- not guaranteed that the direction from the node to the two spheres will be an +-- orthogonal vector. + +local Sphere1 = { + Identifier = "FixedRotation_Example_Moving_TwoObjects_Sphere1", + Transform = { + Translation = { + Type = "StaticTranslation", + Position = { 3.0, -2.0, 0.0 } + } + }, + Renderable = { + Type = "RenderableSphericalGrid" + }, + GUI = { + Name = "FixedRotation - Moving Two Objects (Sphere 1)", + Path = "/Examples" + } +} + +local Sphere2 = { + Identifier = "FixedRotation_Example_Moving_TwoObjects_Sphere2", + Transform = { + Translation = { + Type = "KeplerTranslation", + Eccentricity = 0.5, + SemiMajorAxis = 0.0025, + Inclination = 0.0, + AscendingNode = 0.0, + ArgumentOfPeriapsis = 0.0, + MeanAnomaly = 0.0, + Epoch = "2000 JAN 01 12:00:00", + Period = 10.0 + } + }, + Renderable = { + Type = "RenderableSphericalGrid" + }, + GUI = { + Name = "FixedRotation - Moving Two Objects (Sphere 2)", + Path = "/Examples" + } +} + +local Node = { + Identifier = "FixedRotation_Example_Moving_TwoObjects", + Transform = { + Rotation = { + Type = "FixedRotation", + Attached = "FixedRotation_Example_Moving_TwoObjects", + YAxis = Sphere1.Identifier, + YAxisOrthogonal = true, + ZAxis = Sphere2.Identifier + } + }, + Renderable = { + Type = "RenderableCartesianAxes" + }, + GUI = { + Name = "FixedRotation - Moving Two Objects", + Path = "/Examples" + } +} + +asset.onInitialize(function() + openspace.addSceneGraphNode(Sphere1) + openspace.addSceneGraphNode(Sphere2) + openspace.addSceneGraphNode(Node) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(Node) + openspace.removeSceneGraphNode(Sphere2) + openspace.removeSceneGraphNode(Sphere1) +end) diff --git a/data/assets/examples/rotation/fixedrotation/fixed_moving.asset b/data/assets/examples/rotation/fixedrotation/fixed_moving.asset new file mode 100644 index 0000000000..414dc3da6b --- /dev/null +++ b/data/assets/examples/rotation/fixedrotation/fixed_moving.asset @@ -0,0 +1,63 @@ +-- Rotation Following One Moving Object +-- This asset creates a rotation that places coordinate axes orbiting close to a sphere +-- with the z axis always pointing towards the sphere as it orbits around the sphere. The +-- coordinate axes are translated away from the sphere to make that orientation more +-- obvious. +-- +-- Making the `YAxis` { 0.0, 1.0, 0.0 } and actually using the orthogonal projection of +-- that direction means that the y axis of the new coordinate system will point in the +-- hemisphere in which the old y-axis was pointing, albeit being orthogonal to the other +-- specified axis. That axis is pointing towards the scene graph node holding the sphere. +local Sphere = { + Identifier = "FixedRotation_Example_Moving_Sphere", + Transform = { + Translation = { + Type = "KeplerTranslation", + Eccentricity = 0.5, + SemiMajorAxis = 0.0025, + Inclination = 0.0, + AscendingNode = 0.0, + ArgumentOfPeriapsis = 0.0, + MeanAnomaly = 0.0, + Epoch = "2000 JAN 01 12:00:00", + Period = 10.0 + } + }, + Renderable = { + Type = "RenderableSphericalGrid" + }, + GUI = { + Name = "FixedRotation - Moving (Sphere)", + Path = "/Examples" + } +} + +local Node = { + Identifier = "FixedRotation_Example_Moving", + Transform = { + Rotation = { + Type = "FixedRotation", + Attached = "FixedRotation_Example_Moving", + YAxis = { 0.0, 1.0, 0.0 }, + YAxisOrthogonal = true, + ZAxis = Sphere.Identifier + } + }, + Renderable = { + Type = "RenderableCartesianAxes" + }, + GUI = { + Name = "FixedRotation - Moving", + Path = "/Examples" + } +} + +asset.onInitialize(function() + openspace.addSceneGraphNode(Sphere) + openspace.addSceneGraphNode(Node) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(Node) + openspace.removeSceneGraphNode(Sphere) +end) diff --git a/data/assets/examples/rotation/globerotation/angle.asset b/data/assets/examples/rotation/globerotation/globe_angle.asset similarity index 100% rename from data/assets/examples/rotation/globerotation/angle.asset rename to data/assets/examples/rotation/globerotation/globe_angle.asset diff --git a/data/assets/examples/rotation/globerotation/usecamera.asset b/data/assets/examples/rotation/globerotation/globe_usecamera.asset similarity index 100% rename from data/assets/examples/rotation/globerotation/usecamera.asset rename to data/assets/examples/rotation/globerotation/globe_usecamera.asset diff --git a/data/assets/examples/rotation/luarotation/lua.asset b/data/assets/examples/rotation/luarotation/lua.asset index e20d46fbfb..ae37b0cdb7 100644 --- a/data/assets/examples/rotation/luarotation/lua.asset +++ b/data/assets/examples/rotation/luarotation/lua.asset @@ -1,7 +1,7 @@ -- Basic --- This asset creates a SceneGraphNode that only displays coordinate axes. The rotation of --- coordinate axes are determined by executing a Lua file that returns the rotation matrix --- to be used. +-- This asset creates a scene graph node that only displays coordinate axes. The rotation +-- of coordinate axes are determined by executing a Lua file that returns the rotation +-- matrix to be used. -- -- ```{literalinclude} example.lua -- :language: lua diff --git a/data/assets/examples/rotation/multirotation/multi.asset b/data/assets/examples/rotation/multirotation/multi.asset index c36899c2fe..a593330643 100644 --- a/data/assets/examples/rotation/multirotation/multi.asset +++ b/data/assets/examples/rotation/multirotation/multi.asset @@ -1,6 +1,6 @@ -- Basic --- This asset creates a SceneGraphNode that only displays coordinate axes. The rotation of --- the coordinate axes are determined by a combination of individual rotations. The +-- This asset creates a scene graph node that only displays coordinate axes. The rotation +-- of the coordinate axes are determined by a combination of individual rotations. The -- rotations are applied in the order in which they are specified local Node = { diff --git a/data/assets/examples/rotation/spicerotation/spice.asset b/data/assets/examples/rotation/spicerotation/spice.asset index be46c5f4ba..0aeaed82d0 100644 --- a/data/assets/examples/rotation/spicerotation/spice.asset +++ b/data/assets/examples/rotation/spicerotation/spice.asset @@ -1,8 +1,8 @@ -- Basic --- This asset creates a rotation provided by a SPICE kernel and applies it to a --- SceneGraphNode that only displays coordinate axes. The rotation of the coordinate axes --- are determined by SPICE, in this case pretending that the coordinate axes are rotating --- at the same rate as Earth. +-- This asset creates a rotation provided by a SPICE kernel and applies it to a scene +-- graph node that only displays coordinate axes. The rotation of the coordinate axes are +-- determined by SPICE, in this case pretending that the coordinate axes are rotating at +-- the same rate as Earth. -- For more information about SPICE see: https://naif.jpl.nasa.gov/naif/ -- Load the default SPICE kernels, which are the planetary constants and the DE430 kernel diff --git a/data/assets/examples/rotation/spicerotation/fixeddate.asset b/data/assets/examples/rotation/spicerotation/spice_fixeddate.asset similarity index 66% rename from data/assets/examples/rotation/spicerotation/fixeddate.asset rename to data/assets/examples/rotation/spicerotation/spice_fixeddate.asset index d3c580a656..97654344a9 100644 --- a/data/assets/examples/rotation/spicerotation/fixeddate.asset +++ b/data/assets/examples/rotation/spicerotation/spice_fixeddate.asset @@ -1,9 +1,9 @@ -- Fixed Date --- This asset creates a rotation provided by a SPICE kernel and applies it to a --- SceneGraphNode that only displays coordinate axes. The rotation of the coordinate axes --- are determined by SPICE, in this case pretending that the coordinate axes are rotating --- at the same rate as Earth. In this specific example, the orientation is independent of --- the actual in-game time in OpenSpace and only uses a fixed date of 2000 JAN 01 instead. +-- This asset creates a rotation provided by a SPICE kernel and applies it to a scene +-- graph node that only displays coordinate axes. The rotation of the coordinate axes are +-- determined by SPICE, in this case pretending that the coordinate axes are rotating at +-- the same rate as Earth. In this specific example, the orientation is independent of the +-- actual in-game time in OpenSpace and only uses a fixed date of 2000 JAN 01 instead. -- Load the default SPICE kernels, which is the planetary constants and the DE430 kernel asset.require("spice/core") diff --git a/data/assets/examples/rotation/spicerotation/timeframe.asset b/data/assets/examples/rotation/spicerotation/spice_timeframe.asset similarity index 65% rename from data/assets/examples/rotation/spicerotation/timeframe.asset rename to data/assets/examples/rotation/spicerotation/spice_timeframe.asset index 6eb7eb3f90..326a741c90 100644 --- a/data/assets/examples/rotation/spicerotation/timeframe.asset +++ b/data/assets/examples/rotation/spicerotation/spice_timeframe.asset @@ -1,10 +1,10 @@ -- TimeFrame --- This asset creates a rotation provided by a SPICE kernel and applies it to a --- SceneGraphNode that only displays coordinate axes. The rotation of the coordinate axes --- are determined by SPICE, in this case pretending that the coordinate axes are rotating --- at the same rate as Earth. In this example, the rotation is only calculated between --- 2000 JAN 01 and 2002 JAN 01 to exemplify a use-case in which the data from the SPICE --- kernel is not available for the whole duration. +-- This asset creates a rotation provided by a SPICE kernel and applies it to a scene +-- graph node that only displays coordinate axes. The rotation of the coordinate axes are +-- determined by SPICE, in this case pretending that the coordinate axes are rotating at +-- the same rate as Earth. In this example, the rotation is only calculated between 2000 +-- JAN 01 and 2002 JAN 01 to exemplify a use-case in which the data from the SPICE kernel +-- is not available for the whole duration. -- Load the default SPICE kernels, which is the planetary constants and the DE430 kernel asset.require("spice/core") diff --git a/data/assets/examples/rotation/spicerotation/timeoffset.asset b/data/assets/examples/rotation/spicerotation/spice_timeoffset.asset similarity index 73% rename from data/assets/examples/rotation/spicerotation/timeoffset.asset rename to data/assets/examples/rotation/spicerotation/spice_timeoffset.asset index 73a84dab41..b508f8ddb5 100644 --- a/data/assets/examples/rotation/spicerotation/timeoffset.asset +++ b/data/assets/examples/rotation/spicerotation/spice_timeoffset.asset @@ -1,8 +1,8 @@ -- Time offset --- This asset creates a rotation provided by a SPICE kernel and applies it to a --- SceneGraphNode that only displays coordinate axes. The rotation of the coordinate axes --- are determined by SPICE, in this case pretending that the coordinate axes are rotating --- at the same rate as Earth. In this specific example, the orientation is offset 8h back +-- This asset creates a rotation provided by a SPICE kernel and applies it to a scene +-- graph node that only displays coordinate axes. The rotation of the coordinate axes are +-- determined by SPICE, in this case pretending that the coordinate axes are rotating at +-- the same rate as Earth. In this specific example, the orientation is offset 8h back -- compared to the actual in-game time in OpenSpace. -- Load the default SPICE kernels, which is the planetary constants and the DE430 kernel diff --git a/data/assets/examples/rotation/staticrotation/euler.asset b/data/assets/examples/rotation/staticrotation/static_euler.asset similarity index 76% rename from data/assets/examples/rotation/staticrotation/euler.asset rename to data/assets/examples/rotation/staticrotation/static_euler.asset index 3a8aa929a9..c024e7c0f6 100644 --- a/data/assets/examples/rotation/staticrotation/euler.asset +++ b/data/assets/examples/rotation/staticrotation/static_euler.asset @@ -1,7 +1,7 @@ -- Euler Angles --- This asset creates a rotation provided by Euler angles and applies it to a --- SceneGraphNode that only displays coordinate axes. The rotation of the coordinate axes --- are determined by a constant and unchanging static rotation. +-- This asset creates a rotation provided by Euler angles and applies it to a scene graph +-- node that only displays coordinate axes. The rotation of the coordinate axes are +-- determined by a constant and unchanging static rotation. local Node = { Identifier = "StaticRotation_Example_Euler", diff --git a/data/assets/examples/rotation/staticrotation/matrix.asset b/data/assets/examples/rotation/staticrotation/static_matrix.asset similarity index 70% rename from data/assets/examples/rotation/staticrotation/matrix.asset rename to data/assets/examples/rotation/staticrotation/static_matrix.asset index 60b530da7c..3f996e0815 100644 --- a/data/assets/examples/rotation/staticrotation/matrix.asset +++ b/data/assets/examples/rotation/staticrotation/static_matrix.asset @@ -1,7 +1,7 @@ -- Matrix --- This asset creates a SceneGraphNode that only displays coordinate axes. The rotation of --- the coordinate axes are determined by a constant and unchanging static rotation that is --- provided by a 3-by-3 rotation matrix in column-major order. +-- This asset creates a scene graph node that only displays coordinate axes. The rotation +-- of the coordinate axes are determined by a constant and unchanging static rotation that +-- is provided by a 3-by-3 rotation matrix in column-major order. local Node = { Identifier = "StaticRotation_Example_Matrix", diff --git a/data/assets/examples/rotation/staticrotation/quaternion.asset b/data/assets/examples/rotation/staticrotation/static_quaternion.asset similarity index 69% rename from data/assets/examples/rotation/staticrotation/quaternion.asset rename to data/assets/examples/rotation/staticrotation/static_quaternion.asset index ad1ea3929e..7aac867819 100644 --- a/data/assets/examples/rotation/staticrotation/quaternion.asset +++ b/data/assets/examples/rotation/staticrotation/static_quaternion.asset @@ -1,7 +1,7 @@ -- Quaternion --- This asset creates a SceneGraphNode that only displays coordinate axes. The rotation of --- the coordinate axes are determined by a constant and unchanging static rotation that is --- provided by a four-dimensional quaternion. +-- This asset creates a scene graph node that only displays coordinate axes. The rotation +-- of the coordinate axes are determined by a constant and unchanging static rotation that +-- is provided by a four-dimensional quaternion. local Node = { Identifier = "StaticRotation_Example_Quaternion", diff --git a/data/assets/examples/rotation/timelinerotation/timeline.asset b/data/assets/examples/rotation/timelinerotation/timeline.asset index 51db1d1361..04757d1ef4 100644 --- a/data/assets/examples/rotation/timelinerotation/timeline.asset +++ b/data/assets/examples/rotation/timelinerotation/timeline.asset @@ -1,9 +1,9 @@ -- Basic --- This asset creates a SceneGraphNode that only displays coordinate axes. The rotation of --- the coordinate axes are determined by a timeline of individual rotations. These rotations --- are keyframes that are used to seamlessly change between different orientations. This --- example transitions between three rotations over a long time span. This example will --- only work if the in-game time is set to January 1st, 2000. +-- This asset creates a scene graph node that only displays coordinate axes. The rotation +-- of the coordinate axes are determined by a timeline of individual rotations. These +-- rotations are keyframes that are used to seamlessly change between different +-- orientations. This example transitions between three rotations over a long time span. +-- This example will only work if the in-game time is set to January 1st, 2000. local Node = { Identifier = "TimelineRotation_Example", diff --git a/data/assets/examples/rotation/timelinerotation/no-interpolate.asset b/data/assets/examples/rotation/timelinerotation/timeline_no-interpolate.asset similarity index 56% rename from data/assets/examples/rotation/timelinerotation/no-interpolate.asset rename to data/assets/examples/rotation/timelinerotation/timeline_no-interpolate.asset index 5980216e71..376fa9fa35 100644 --- a/data/assets/examples/rotation/timelinerotation/no-interpolate.asset +++ b/data/assets/examples/rotation/timelinerotation/timeline_no-interpolate.asset @@ -1,13 +1,13 @@ -- No Interpolation --- This asset creates a SceneGraphNode that only displays coordinate axes. The rotation of --- the coordinate axes are determined by a timeline of individual rotations that are used --- without interpolating between the timeline entries. These rotations are keyframes that --- are used to change between different orientations. This example transitions between --- three rotations. In this example, the interpolation between entries is disabled, which --- will cause the coordinate axes to change their orientation abruptly when the rotation --- changes. If the interpolation were enabled, the orientation of the coordinate axes --- would transition seamlessly instead at the provided times. This example will only work --- if the in-game time is set to January 1st, 2000. +-- This asset creates a scene graph node that only displays coordinate axes. The rotation +-- of the coordinate axes are determined by a timeline of individual rotations that are +-- used without interpolating between the timeline entries. These rotations are keyframes +-- that are used to change between different orientations. This example transitions +-- between three rotations. In this example, the interpolation between entries is +-- disabled, which will cause the coordinate axes to change their orientation abruptly +-- when the rotation changes. If the interpolation were enabled, the orientation of the +-- coordinate axes would transition seamlessly instead at the provided times. This example +-- will only work if the in-game time is set to January 1st, 2000. local Node = { Identifier = "TimelineRotation_Example_NoInterpolation", diff --git a/data/assets/examples/scale/luascale/lua.asset b/data/assets/examples/scale/luascale/lua.asset index b36911727b..17a2271946 100644 --- a/data/assets/examples/scale/luascale/lua.asset +++ b/data/assets/examples/scale/luascale/lua.asset @@ -1,5 +1,5 @@ -- Basic --- This asset creates a SceneGraphNode that only displays coordinate axes. The sizes of +-- This asset creates a scene graph node that only displays coordinate axes. The sizes of -- coordinate axes are determined by executing a Lua file that returns the scaling -- parameters to be used as a table. -- diff --git a/data/assets/examples/scale/multiscale/multi.asset b/data/assets/examples/scale/multiscale/multi.asset index fd3b6c6992..56237700be 100644 --- a/data/assets/examples/scale/multiscale/multi.asset +++ b/data/assets/examples/scale/multiscale/multi.asset @@ -1,5 +1,5 @@ -- Basic --- This asset creates a SceneGraphNode that only displays coordinate axes, with a set of +-- This asset creates a scene graph node that only displays coordinate axes, with a set of -- multiple scales that are applied one after the other. local Node = { diff --git a/data/assets/examples/scale/nonuniformstaticscale/nonuniformstatic.asset b/data/assets/examples/scale/nonuniformstaticscale/nonuniformstatic.asset index a0bfdef597..7f44c6edd1 100644 --- a/data/assets/examples/scale/nonuniformstaticscale/nonuniformstatic.asset +++ b/data/assets/examples/scale/nonuniformstaticscale/nonuniformstatic.asset @@ -1,10 +1,10 @@ -- Basic --- This asset creates a SceneGraphNode that only displays coordinate axes. The coordinate --- axis normally have a length of 1 meter and are scaled in this example by different --- values for each axis. The x axis is scaled by a factor of 149597870700, which means --- they will be 149597870700 m (1 AU) long and thus reaching the same distance as Earth's --- orbit around the Sun. The y-axis stays at its original size, and the z-axis will be --- hidden entirely by setting the scale value close to 0. +-- This asset creates a scene graph node that only displays coordinate axes. The +-- coordinate axis normally have a length of 1 meter and are scaled in this example by +-- different values for each axis. The x axis is scaled by a factor of 149597870700, which +-- means they will be 149597870700 m (1 AU) long and thus reaching the same distance as +-- Earth's orbit around the Sun. The y-axis stays at its original size, and the z-axis +-- will be hidden entirely by setting the scale value close to 0. local Node = { Identifier = "NonUniformStaticScale_Example", diff --git a/data/assets/examples/scale/nonuniformstaticscale/nonuniformstatic_ellipsoid.asset b/data/assets/examples/scale/nonuniformstaticscale/nonuniformstatic_ellipsoid.asset index 4f6a1c8169..2fdbb125c9 100644 --- a/data/assets/examples/scale/nonuniformstaticscale/nonuniformstatic_ellipsoid.asset +++ b/data/assets/examples/scale/nonuniformstaticscale/nonuniformstatic_ellipsoid.asset @@ -1,5 +1,5 @@ -- Ellipsoid --- This asset creates a SceneGraphNode that is rendering a sphere which is adjust to an +-- This asset creates a scene graph node that is rendering a sphere which is adjust to an -- ellipsoidal shape by using a non-uniform scaling. In particular, the second axis is -- half as long as the first, and the third axis is a third as long. diff --git a/data/assets/examples/scale/staticscale/static.asset b/data/assets/examples/scale/staticscale/static.asset index bde46f25d0..8d1c280d75 100644 --- a/data/assets/examples/scale/staticscale/static.asset +++ b/data/assets/examples/scale/staticscale/static.asset @@ -1,8 +1,8 @@ -- Basic --- This asset creates a SceneGraphNode that only displays coordinate axes. The coordinate --- axis normally have a length of 1 meter and are scaled in this example by a factor of --- 149597870700, which means they will be 149597870700 m (1 AU) long, thus reaching the --- same distance as Earth's orbit around the Sun. +-- This asset creates a scene graph node that only displays coordinate axes. The +-- coordinate axis normally have a length of 1 meter and are scaled in this example by a +-- factor of 149597870700, which means they will be 149597870700 m (1 AU) long, thus +-- reaching the same distance as Earth's orbit around the Sun. local Node = { Identifier = "StaticScale_Example", diff --git a/data/assets/examples/scale/timedependentscale/timedependent.asset b/data/assets/examples/scale/timedependentscale/timedependent.asset index 80db2ffbc7..91d598c197 100644 --- a/data/assets/examples/scale/timedependentscale/timedependent.asset +++ b/data/assets/examples/scale/timedependentscale/timedependent.asset @@ -1,5 +1,5 @@ -- Basic --- This asset creates a SceneGraphNode that only displays coordinate axes, which grow at +-- This asset creates a scene graph node that only displays coordinate axes, which grow at -- a speed of 1 m/s starting on January 1st, 2000 00:00:00. This means that on -- that date, the coordinate axes will disappear and, for example, on January 1st, 2000 -- 12:00:00, the coordinate axes will be 43200 meters long. diff --git a/data/assets/examples/scale/timedependentscale/timedependent_speed.asset b/data/assets/examples/scale/timedependentscale/timedependent_speed.asset index 77e353d259..6dfaac3816 100644 --- a/data/assets/examples/scale/timedependentscale/timedependent_speed.asset +++ b/data/assets/examples/scale/timedependentscale/timedependent_speed.asset @@ -1,5 +1,5 @@ -- with Speed --- This asset creates a SceneGraphNode that only displays coordinate axes, which grow at +-- This asset creates a scene graph node that only displays coordinate axes, which grow at -- a speed of 12 km/s starting on August 8th, 1969 12:00:00. This means that on -- that date, the coordinate axes will disappear and, for example, on August 8th, 1969 -- 23:00:00, the coordinate axes will be 475200 km long. diff --git a/data/assets/examples/scale/timelinescale/timeline.asset b/data/assets/examples/scale/timelinescale/timeline.asset index 3029f4d148..6ed4f59522 100644 --- a/data/assets/examples/scale/timelinescale/timeline.asset +++ b/data/assets/examples/scale/timelinescale/timeline.asset @@ -1,5 +1,5 @@ -- Basic --- This asset creates a SceneGraphNode that only displays coordinate axes. The scale of +-- This asset creates a scene graph node that only displays coordinate axes. The scale of -- the coordinate axes are determined by a timeline of individual scales. These scales -- are keyframes that are used to seamlessly change between different sizes. This example -- transitions between three scales over a long time span. This example will only work if diff --git a/data/assets/examples/scale/timelinescale/no-interpolate.asset b/data/assets/examples/scale/timelinescale/timeline_no-interpolate.asset similarity index 53% rename from data/assets/examples/scale/timelinescale/no-interpolate.asset rename to data/assets/examples/scale/timelinescale/timeline_no-interpolate.asset index 76d5f54ec3..abcdbffd9b 100644 --- a/data/assets/examples/scale/timelinescale/no-interpolate.asset +++ b/data/assets/examples/scale/timelinescale/timeline_no-interpolate.asset @@ -1,13 +1,14 @@ -- No Interpolation --- This asset creates a SceneGraphNode that only displays coordinate axes. The scale of --- the coordinate axes are determined by a timeline of individual scales that are used --- without interpolating between the timeline entries. These scales are keyframes that are --- used to change between different sizes. This example transitions between three sizes. --- In this example, the interpolation between entries is disabled, which will cause the --- coordinate axes to change their size abruptly when the scale changes. If the --- interpolation were enabled, the orientation of the coordinate axes would transition --- seamlessly instead at the provided times. This example will only work if the in-game --- time is set to January 1st, 2000. +-- This asset creates a scene graph node that only displays coordinate axes whose scale is +-- determined by a timeline of individual scales that are used without interpolating +-- between the timeline entries. These scales are keyframes that are used to change +-- between different sizes. +-- +-- This example transitions between three sizes, but as the interpolation between entries +-- is disabled, it will cause the coordinate axes to change their size abruptly when the +-- scale changes. If the interpolation were enabled, the orientation of the coordinate +-- axes would transition seamlessly instead at the provided times. This example will only +-- work if the in-game time is set to January 1st, 2000. local Node = { Identifier = "TimelineScale_Example_NoInterpolation", @@ -18,17 +19,17 @@ local Node = { -- The first timeline entry ["2000 JAN 01 00:00:00"] = { Type = "StaticScale", - Scale = 20.0 + Scale = 10.0 }, -- The second timeline entry ["2000 JAN 01 12:00:00"] = { Type = "StaticScale", - Scale = 10.0 + Scale = 0.0 }, -- The third timeline entry ["2000 JAN 01 23:59:59"] = { Type = "StaticScale", - Scale = 20.0 + Scale = -10.0 } }, ShouldInterpolate = false diff --git a/data/assets/examples/screenspacedistancetoearth.asset b/data/assets/examples/screenspacedistancetoearth.asset index 8200f392a1..3ef61d806f 100644 --- a/data/assets/examples/screenspacedistancetoearth.asset +++ b/data/assets/examples/screenspacedistancetoearth.asset @@ -16,7 +16,7 @@ local Dashboard = { FontSize = 40, SourceType = "Camera", DestinationType = "Node", - DestinationNodeName = earth.Earth.Identifier, + DestinationNodeIdentifier = earth.Earth.Identifier, -- Specify to use a specific unit, by disabling the automatic simplification of -- unit and instead use light-years Simplification = false, diff --git a/data/assets/examples/screenspacerenderable/screenspaceinsetblackout/insetblackout.asset b/data/assets/examples/screenspacerenderable/screenspaceinsetblackout/insetblackout.asset new file mode 100644 index 0000000000..d5a5dff740 --- /dev/null +++ b/data/assets/examples/screenspacerenderable/screenspaceinsetblackout/insetblackout.asset @@ -0,0 +1,23 @@ +-- Basic +-- Creates a screenspace image plane with controls to for a blackout shape. Can be used +-- when using a secondary projector to project content on a dome surface. + +local inset = { + Identifier = "ScreenSpaceInsetBlackout_Example", + Type = "ScreenSpaceInsetBlackout", + Name = "ScreenSpaceInsetBlackout Example - Basic", + Blackoutshape = { + -- Must always contain four corners in the following order: + -- top-left, top-right, bottom-right, bottom-left + Corners = { {0.0, 1.0}, {1.0, 1.0}, {1.0, 0.0}, {0.0, 0.0} } + }, + Scale = 1.0 +} + +asset.onInitialize(function() + openspace.addScreenSpaceRenderable(inset) +end) + +asset.onDeinitialize(function() + openspace.removeScreenSpaceRenderable(inset) +end) diff --git a/data/assets/examples/screenspacerenderable/screenspaceinsetblackout/insetblackout_calibration_pattern.asset b/data/assets/examples/screenspacerenderable/screenspaceinsetblackout/insetblackout_calibration_pattern.asset new file mode 100644 index 0000000000..b89c82ace2 --- /dev/null +++ b/data/assets/examples/screenspacerenderable/screenspaceinsetblackout/insetblackout_calibration_pattern.asset @@ -0,0 +1,32 @@ +-- Calibration Pattern +-- Creates a screenspace image plane with controls to for a blackout shape. Can be used +-- when using a secondary projector to project content on a dome surface. + +local texturePath = asset.resource({ + Type = "HttpSynchronization", + Identifier = "calibration_pattern", + Name = "ScreenSpaceInsetBlackout Calibration Pattern", + Version = 1 +}) + +local inset = { + Identifier = "ScreenSpaceInsetBlackout_Example_Calibration_Pattern", + Type = "ScreenSpaceInsetBlackout", + Name = "ScreenSpaceInsetBlackout Example - Calibration Pattern", + Blackoutshape = { + -- Must always contain four corners in the following order: + -- top-left, top-right, bottom-right, bottom-left + Corners = { { 0.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 0.0 }, { 0.0, 0.0 } }, + CalibrationTexturePath = texturePath .. "calibration-pattern.png", + EnableCalibrationPattern = true + }, + Scale = 1.0 +} + +asset.onInitialize(function() + openspace.addScreenSpaceRenderable(inset) +end) + +asset.onDeinitialize(function() + openspace.removeScreenSpaceRenderable(inset) +end) diff --git a/data/assets/examples/screenspacerenderable/screenspaceinsetblackout/insetblackout_points.asset b/data/assets/examples/screenspacerenderable/screenspaceinsetblackout/insetblackout_points.asset new file mode 100644 index 0000000000..29540bc565 --- /dev/null +++ b/data/assets/examples/screenspacerenderable/screenspaceinsetblackout/insetblackout_points.asset @@ -0,0 +1,35 @@ +-- Points +-- Creates a screenspace image plane with controls to for a blackout shape. Can be used +-- when using a secondary projector to project content on a dome surface. + +local inset = { + Identifier = "ScreenSpaceInsetBlackout_Example_Points", + Type = "ScreenSpaceInsetBlackout", + Name = "ScreenSpaceInsetBlackout Example - Points", + Blackoutshape = { + -- Must always contain four corners in the following order: + -- top-left, top-right, bottom-right, bottom-left + Corners = { {0.0, 0.9}, {1.0, 0.9}, {0.9, 0.1}, {0.1, 0.1} }, + + -- Contains control points for top spline in order left to right + Top = { {0.5, 1.0} }, + + -- Contains control points for right spline in order top to bottom + Right = { }, + + -- Contains control points for bottom spline in order right to left + Bottom = { {0.7, 0.2}, {0.3, 0.2} }, + + -- Contains control points for left spline in order bottom to top + Left = { } + }, + Scale = 1.0 +} + +asset.onInitialize(function() + openspace.addScreenSpaceRenderable(inset) +end) + +asset.onDeinitialize(function() + openspace.removeScreenSpaceRenderable(inset) +end) diff --git a/data/assets/examples/screenspacerenderable/screenspacerenderablerenderable/renderablerenderable.asset b/data/assets/examples/screenspacerenderable/screenspacerenderablerenderable/renderablerenderable.asset new file mode 100644 index 0000000000..636a0d96b8 --- /dev/null +++ b/data/assets/examples/screenspacerenderable/screenspacerenderablerenderable/renderablerenderable.asset @@ -0,0 +1,22 @@ +-- Basic +-- Creates a screenspace image that shows a spherical grid as an example for any +-- [Renderable](#renderable) that can be displayed. + +local Object = { + Type = "ScreenSpaceRenderableRenderable", + Identifier = "ScreenSpaceRenderableRenderable_Example", + Renderable = { + Type = "RenderableSphericalGrid", + Opacity = 1.0, + Color = { 0.3, 0.84, 1.0 }, + LineWidth = 2.0 + } +} + +asset.onInitialize(function() + openspace.addScreenSpaceRenderable(Object) +end) + +asset.onDeinitialize(function() + openspace.removeScreenSpaceRenderable(Object) +end) diff --git a/data/assets/examples/screenspacerenderable/screenspacerenderablerenderable/renderablerenderable_axes.asset b/data/assets/examples/screenspacerenderable/screenspacerenderablerenderable/renderablerenderable_axes.asset new file mode 100644 index 0000000000..48e264e518 --- /dev/null +++ b/data/assets/examples/screenspacerenderable/screenspacerenderablerenderable/renderablerenderable_axes.asset @@ -0,0 +1,24 @@ +-- Axes +-- Creates a screenspace image that renders three Cartesian axes into the screen space +-- window. This example also modifies the original camera position to give an oblique view +-- onto the axes and increases the field of view of the camera to a wider degree. We also +-- set the background color to be fully opaque to make it easier to see the axes. + +local Object = { + Type = "ScreenSpaceRenderableRenderable", + Identifier = "ScreenSpaceRenderableRenderable_Example_Axes", + Renderable = { + Type = "RenderableCartesianAxes" + }, + BackgroundColor = { 0.0, 0.0, 0.0, 1.0 }, + CameraPosition = { 1.0, 1.0, 1.0 }, + CameraFov = 80.0 +} + +asset.onInitialize(function() + openspace.addScreenSpaceRenderable(Object) +end) + +asset.onDeinitialize(function() + openspace.removeScreenSpaceRenderable(Object) +end) diff --git a/data/assets/examples/screenspacerenderable/screenspacerenderablerenderable/renderablerenderable_model-distance.asset b/data/assets/examples/screenspacerenderable/screenspacerenderablerenderable/renderablerenderable_model-distance.asset new file mode 100644 index 0000000000..ec19a4bd1b --- /dev/null +++ b/data/assets/examples/screenspacerenderable/screenspacerenderablerenderable/renderablerenderable_model-distance.asset @@ -0,0 +1,41 @@ +-- Model Distance +-- Creates a screen space window into which 3D model of the Eiffel tower is rendered. As +-- the objects are rendered in meter scale, and the Eiffel tower is about 300m tall, we +-- place the camera at a great distance to be able to see the entire Eiffel tower at the +-- same time. + +-- Download the model file for the Eiffel tower +local modelFolder = asset.resource({ + Name = "Scale Eiffel Tower", + Type = "HttpSynchronization", + Identifier = "scale_model_eiffel_tower", + Version = 1 +}) + +local Object = { + Type = "ScreenSpaceRenderableRenderable", + Identifier = "ScreenSpaceRenderableRenderable_Example_ModelDistance", + Renderable = { + Type = "RenderableModel", + GeometryFile = modelFolder .. "eiffeltower.osmodel", + RotationVector = { 0.0, 45.0, 0.0 }, + LightSources = { + { + Identifier = "Camera", + Type = "CameraLightSource", + Intensity = 5.0 + } + } + }, + Scale = 1.25, + CameraPosition = { 0.0, 3500.0, 9000.0 }, + CameraCenter = { 0.0, 2750.0, 0.0 } +} + +asset.onInitialize(function() + openspace.addScreenSpaceRenderable(Object) +end) + +asset.onDeinitialize(function() + openspace.removeScreenSpaceRenderable(Object) +end) diff --git a/data/assets/examples/screenspacerenderable/screenspacerenderablerenderable/renderablerenderable_model.asset b/data/assets/examples/screenspacerenderable/screenspacerenderablerenderable/renderablerenderable_model.asset new file mode 100644 index 0000000000..19abddfac3 --- /dev/null +++ b/data/assets/examples/screenspacerenderable/screenspacerenderablerenderable/renderablerenderable_model.asset @@ -0,0 +1,47 @@ +-- Model +-- Creates a screen space window into which 3D model of the Eiffel tower is rendered. As +-- the objects are rendered in meter scale, and the Eiffel tower is about 300m tall, we +-- both shrink the rendering to make the entire model fit into the view and also modify +-- the position of the camera. + +-- Download the model file for the Eiffel tower +local modelFolder = asset.resource({ + Name = "Scale Eiffel Tower", + Type = "HttpSynchronization", + Identifier = "scale_model_eiffel_tower", + Version = 1 +}) + +local Object = { + Type = "ScreenSpaceRenderableRenderable", + Identifier = "ScreenSpaceRenderableRenderable_Example_Model", + Transform = { + Scale = { + Type = "StaticScale", + Scale = 0.0002 + } + }, + Renderable = { + Type = "RenderableModel", + GeometryFile = modelFolder .. "eiffeltower.osmodel", + RotationVector = { 0.0, 45.0, 0.0 }, + LightSources = { + { + Identifier = "Camera", + Type = "CameraLightSource", + Intensity = 5.0 + } + } + }, + Scale = 1.25, + CameraPosition = { 0.0, 1.0, 2.0 }, + CameraCenter = { 0.0, 0.5, 0.0 } +} + +asset.onInitialize(function() + openspace.addScreenSpaceRenderable(Object) +end) + +asset.onDeinitialize(function() + openspace.removeScreenSpaceRenderable(Object) +end) diff --git a/data/assets/examples/screenspacerenderable/screenspacetimevaryingimageonline/data/example.json b/data/assets/examples/screenspacerenderable/screenspacetimevaryingimageonline/data/example.json new file mode 100644 index 0000000000..228e23d59d --- /dev/null +++ b/data/assets/examples/screenspacerenderable/screenspacetimevaryingimageonline/data/example.json @@ -0,0 +1,16 @@ +{ + "files": [ + { + "timestamp": "2024-05-10 15:00:00.000", + "url": "http://data.openspaceproject.com/examples/renderableplaneimageonline.jpg" + }, + { + "timestamp": "2024-05-10 15:10:00.000", + "url": "https://data.openspaceproject.com/examples/renderableplaneimageonline_2.jpg" + }, + { + "timestamp": "2024-05-10 15:20:00.000", + "url": "http://data.openspaceproject.com/examples/renderableplaneimageonline.jpg" + } + ] +} diff --git a/data/assets/examples/screenspacerenderable/screenspacetimevaryingimageonline/timevaryingimageonline.asset b/data/assets/examples/screenspacerenderable/screenspacetimevaryingimageonline/timevaryingimageonline.asset new file mode 100644 index 0000000000..8feef5dbb7 --- /dev/null +++ b/data/assets/examples/screenspacerenderable/screenspacetimevaryingimageonline/timevaryingimageonline.asset @@ -0,0 +1,18 @@ +-- Basic +-- Create a time-varying screenspace image plane that shows the content of images from +-- web URLs based on in-game simulation time. The data in this example has images shown at +-- 2024-05-10 between 15:00:00 and 15:20:00. + +local Item = { + Type = "ScreenSpaceTimeVaryingImageOnline", + Identifier = "ScreenSpaceTimeVaryingImageOnline_Example", + FilePath = asset.resource("data/example.json") +} + +asset.onInitialize(function() + openspace.addScreenSpaceRenderable(Item) +end) + +asset.onDeinitialize(function() + openspace.removeScreenSpaceRenderable(Item) +end) diff --git a/data/assets/examples/slidedeck.asset b/data/assets/examples/slidedeck.asset index 540c11b693..c8cc55f51e 100644 --- a/data/assets/examples/slidedeck.asset +++ b/data/assets/examples/slidedeck.asset @@ -11,8 +11,8 @@ asset.onInitialize(function() Scale = 0.7 }) - helper.addSlide(deck, "${DATA}/test2.jpg") - helper.addSlide(deck, "${DATA}/test3.jpg") + helper.addSlide(deck, openspace.absPath("${DATA}/test2.jpg")) + helper.addSlide(deck, openspace.absPath("${DATA}/test3.jpg")) local interpolationDuration = 0.5 diff --git a/data/assets/examples/sonification/Greetings_from_Earth_mono.wav b/data/assets/examples/sonification/Greetings_from_Earth_mono.wav new file mode 100644 index 0000000000..367f36df8e Binary files /dev/null and b/data/assets/examples/sonification/Greetings_from_Earth_mono.wav differ diff --git a/data/assets/examples/sonification/nodes-space-stations.asset b/data/assets/examples/sonification/nodes-space-stations.asset new file mode 100644 index 0000000000..d2dac92604 --- /dev/null +++ b/data/assets/examples/sonification/nodes-space-stations.asset @@ -0,0 +1,21 @@ +-- Nodes sonification +-- This example adds the ISS and Tiangong space stations to the NodesTelemetry in the +-- Telemetry module. This should be used together with the nodesSonification.scd file in +-- SuperCollider to listen to an example sonification of the nodes. +-- +-- This is a good foundation for creating your own sonification of any node(s) in +-- OpenSpace. If you want to use this to create your own sonification, you can copy this +-- file and the nodesSonification.scd file to your own asset folder and modify them to +-- your liking. In this file, that modification would be to replace the ISS and Tiangong +-- identifies with the identifiers of the node(s) you want to sonify instead. +-- +-- For more information about sonification in OpenSpace and how to use it, see the +-- documentation: +-- https://docs.openspaceproject.com/latest/creating-data-assets/modules/telemetry/sonification.html + +asset.require("scene/solarsystem/planets/earth/satellites/misc/iss") +asset.require("scene/solarsystem/planets/earth/satellites/misc/tiangong") + +asset.onInitialize(function () + openspace.telemetry.addNodes({ "ISS", "Tiangong" }) +end) diff --git a/data/assets/examples/sonification/nodes-voyager.asset b/data/assets/examples/sonification/nodes-voyager.asset new file mode 100644 index 0000000000..3209fd70ed --- /dev/null +++ b/data/assets/examples/sonification/nodes-voyager.asset @@ -0,0 +1,21 @@ +-- Voyager sonification +-- This example adds the Voyager 1 and Voyager 2 probes to the NodesTelemetry in the +-- Telemetry module. This should be used together with the voyager-sonification.scd file +-- in SuperCollider to listen to an example sonification of the Voyager probes. +-- +-- This is a good foundation for creating your own sonification of any node(s) in +-- OpenSpace. If you want to use this to create your own sonification, you can copy this +-- file and the voyager-sonification.scd file to your own asset folder and modify them to +-- your liking. In this file, that modification would be to replace the Voyager 1 and 2 +-- identifiers with the identifiers of the node(s) you want to sonify instead. +-- +-- For more information about sonification in OpenSpace and how to use it, see the +-- documentation: +-- https://docs.openspaceproject.com/latest/creating-data-assets/modules/telemetry/sonification.html + +asset.require("scene/solarsystem/missions/voyager/voyager1") +asset.require("scene/solarsystem/missions/voyager/voyager2") + +asset.onInitialize(function () + openspace.telemetry.addNodes({ "Voyager_1", "Voyager_2" }) +end) diff --git a/data/assets/examples/sonification/osc-example.scd b/data/assets/examples/sonification/osc-example.scd new file mode 100644 index 0000000000..e416f4f1b5 --- /dev/null +++ b/data/assets/examples/sonification/osc-example.scd @@ -0,0 +1,438 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2025 * + * * + * 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. * + ****************************************************************************************/ + +Platform.userExtensionDir +NetAddr.langPort; +NetAddr.localAddr; + +/***************************************************************************************** + * This is a SuperCollider file that needs to be run in the SuperCollider application * + * that can be downloaded here: https://supercollider.github.io/ * + * * + * This is an example file that shows all the messages that the Telemetry module in * + * OpenSpace can send over Open Sound Control (OSC). SuperCollider can then listen to * + * these OSC messages and create sounds based on their content (a sonification). This * + * example only listens to the messages and displays their content in the log to the * + * right in the SuperCollider application. For a more extensive example that shows how * + * to create sounds in SuperCollider based on the data from OpenSpace, see the * + * planets-sonification.scd file located in data\assets\modules\telemetry\sonification. * + * * + * To run a SuperCollider file, click any line within the parentheses below, such as the * + * marked line. When you have selected a line, press the CTRL and ENTER keys on your * + * keyboard at the same time, and SuperCollider will run the code. You will see a * + * message appear in the log to the right, the message should be: * + * "-> OSCdef(Neptune, /Neptune, nil, nil, nil)". At this point, SuperCollider is ready * + * to receive messages from OpenSpace. For a guide on how to enable and use the * + * Telemetry module inside OpenSpace, see this documentation page: * + * https://docs.openspaceproject.com/latest/creating-data-assets/modules/telemetry/ * + * index.html * + ****************************************************************************************/ + +( + +// To run this example, click this line and press CTRL + ENTER on the keyboard +// When finished, press CTRL + . on you keyboard simultaneously to stop the sonification + +// Camera sonification +OSCdef.new( + \Camera, + { + arg msg; + + // msg[0] = OSC Label. + // msg[1] = The x position of the camera in the world. + // msg[2] = The y position of the camera in the world. + // msg[3] = The z position of the camera in the world. + // msg[4] = The w component of the quaternion rotation of the camera. + // msg[5] = The x component of the quaternion rotation of the camera. + // msg[6] = The y component of the quaternion rotation of the camera. + // msg[7] = The z component of the quaternion rotation of the camera. + // msg[8] = The movement speed of the camera, in the distance unit per second + // specified by the next item. + // msg[9] = The distance unit for the movement speed of the camera, as a string in + // singular form with the first letter capitalized. For example, + // "Kilometer". + // + // Note that the first seven items describe the position and orientation of the + // camera. The first three items specify the x, y, and z positions of the camera + // in the world, in relation to the solar system barycenter. The next four items + // are the quaternion rotation of the camera in the order of w, x, y, and z. + + ("Camera: " + msg).postln; + }, + '/Camera' +); + +// Focus sonification +OSCdef.new( + \Focus, + { + arg msg; + + // msg[0] = OSC Label. + // msg[1] = The identifier of the new focus in OpenSpace, as a string. + + ("Focus: " + msg).postln; + }, + '/Focus' +); + +// Surround mode sonification +OSCdef.new( + \Mode, + { + arg msg; + + // msg[0] = OSC Label. + // msg[1] = The first item is an integer value that specifies what method was + // used to calculate the angles. If the value is 0, then the method + // used was the Horizontal angle calculation mode. In the case where + // the value is 1, then the Circular angle calculation mode was used. + // msg[2] = The second value is an integer value of either 0 or 1 that + // determines if the additional elevation angle is used or not. If the + // value is 1, the additional elevation angle is calculated. Otherwise, + // if 0, the elevation angle is always set to 0.0. + + ("Mode: " + msg).postln; + }, + '/Mode' +); + +// Time sonification +OSCdef.new( + \Time, + { + arg msg; + + // msg[0] = OSC Label. + // msg[1] = The speed of the simulation time, specified in the selected time unit + // in the simulation, per real-life second. For example, 10 simulated + // seconds per real-life second means that the simulation goes 10 times + // faster than real-life. + // msg[2] = The selected time unit for the speed of simulation time, as a string + // in singular form with the first letter capitalized. For example, + // "Day". + // msg[3] = The current simulation time in OpenSpace specified in J2000 seconds, + // that is, the number of seconds past the J2000 epoch + // (i.e. January 1, 2000 12:00:00 TT). + + ("Time: " + msg).postln; + }, + '/Time' +); + +// Nodes sonification, data map: +// msg[0] = OSC Label (The identifier for each node). +// msg[1] = The distance from the camera to the node, in the distance unit specified in +// the last item. +// msg[2] = The horizontal angle to the node, in radians, with the current angle +// calculation mode taken into account. For more information, see +// https://docs.openspaceproject.com/latest/creating-data-assets/modules/ +// telemetry/angle-information.html. +// msg[3] = The elevation angle to the node, in radians, with the current angle +// calculation mode taken into account. Again, see +// https://docs.openspaceproject.com/latest/creating-data-assets/modules/ +// telemetry/angle-information.html for details. +// msg[4] = The unit for the distance to the camera, as a string in singular form with +// the first letter capitalized. For example, "Meter". + +// ISS node +OSCdef.new( + \ISS, + { + arg msg; + + // Follow the nodes sonification data map above + + ("ISS: " + msg).postln; + }, + '/ISS' +); + +// Tiangong node +OSCdef.new( + \Tiangong, + { + arg msg; + + // Follow the nodes sonification data map above + + ("Tiangong: " + msg).postln; + }, + '/Tiangong' +); + + +// Planet related sonifications: +// Compare planets +OSCdef.new( + \Compare, + { + arg msg; + + // msg[0] = OSC Label. + // msg[1] = The index of the first planet to be compared. See the list below on + // how to convert the index to a planet name: + // 0 -> None selected + // 1 -> Mercury + // 2 -> Venus + // 3 -> Earth + // 4 -> Mars + // 5 -> Jupiter + // 6 -> Saturn + // 7 -> Uranus + // 8 -> Neptune + // msg[2] = The index of the second planet to be compared (will never be the same + // as the first). + // msg[3] = List of user interface settings for the comparison, which determines + // which aspects of the sonification should be turned on or off. A value + // of 0 means that a setting is turned off, and 1 means that it is turned + // on. The order of the settings can be seen in the list below: + // msg[3][0] = Size/day. 1 -> Size/day is turned on. + // 0 -> Size/day is turned off. + // msg[3][1] = Gravity + // msg[3][2] = Temperature + // msg[3][3] = Atmosphere + // msg[3][4] = Moons + // msg[3][5] = Rings + + ("Compare: " + msg).postln; + + }, + '/Compare' +); + +// Planets overview +OSCdef.new( + \Overview, + { + arg msg; + + // msg[0] = OSC Label. + // msg[1] = List of user interface settings for the planets overview. This + // determines which planets are part of the sonification or not. A value + // of 0 means that the planet is turned off, and a 1 means that it is + // turned on. The order of the settings can be seen in the list below: + // msg[1][0] = Mercury. 1 -> Mercury is turned on. + // 0 -> Mercury is turned off. + // msg[1][1] = Venus + // msg[1][2] = Earth + // msg[1][3] = Mars + // msg[1][4] = Jupiter + // msg[1][5] = Saturn + // msg[1][6] = Uranus + // msg[1][7] = Neptune + + ("Overview: " + msg).postln; + }, + '/Overview' +); + +// Planets sonifications, data map: +// msg[0] = OSC Label (The name of the planet). +// msg[1] = The distance from the camera to the planet in kilometers. +// msg[2] = The horizontal angle in radians to the planet, with the current angle +// calculation mode taken into account. For more information see +// https://docs.openspaceproject.com/latest/creating-data-assets/modules/ +// telemetry/angle-information.html. +// msg[3] = The elevation angle in radians to the planet, with the current angle +// calculation mode taken into account. Again, see +// https://docs.openspaceproject.com/latest/creating-data-assets/modules/ +// telemetry/angle-information.html for details. +// msg[4] = List of user interface settings for the planet sonification, which aspects +// of the sonification should be turned on or off. A value of 0 means that it +// is turned off, and a 1 means that it is turned on. The order of the +// settings can be seen in the table below. If the setting does not exist for +// a planet, the value is always 0. +// msg[4][0] = Size/day. 1 -> Size/day is turned on. +// 0 -> Size/day is turned off. +// msg[4][1] = Gravity +// msg[4][2] = Temperature +// msg[4][3] = Atmosphere +// msg[4][4] = Moons +// msg[4][5] = Rings +// msg[5] = (optional) The distance from the camera to the first moon in kilometers. +// msg[6] = (optional) The horizontal angle in radians to the first moon. +// msg[7] = (optional) The elevation angle in radians to the first moon. +// msg[8] = (optional) The distance from the camera to the second moon in kilometers. +// msg[9] = (optional) The horizontal angle in radians to the second moon. +// msg[10] = (optional) The elevation angle in radians to the second moon. +// msg[...] = The data then continues in the same pattern for each of the planet's +// moons, with three values per moon. The moons are given in order of +// distance from the planet (closest first, farthest last) as specified in +// the planets.asset file in the data\assets\modules\telemetry\sonification +// folder. + +// Mercury +OSCdef.new( + \Mercury, + { + arg msg; + + // Follow the planets sonification data map above + // Mercury does not have the GUI settings: + // - Atmosphere + // - Moons + // - Rings + // Mercury have no moon data since it does not have any moon + + ("Mercury: " + msg).postln; + }, + '/Mercury' +); + +// Venus +OSCdef.new( + \Venus, + { + arg msg; + + // Follow the planets sonification data map above + // Venus does not have the GUI settings: + // - Moons + // - Rings + // Venus have no moon data since it does not have any moon + + ("Venus: " + msg).postln; + }, + '/Venus' +); + +// Earth +OSCdef.new( + \Earth, + { + arg msg; + + // Follow the planets sonification data map above + // Earth does not have the GUI settings: + // - Rings + // Earth have moon data for one moon: + // - The Moon + + ("Earth: " + msg).postln; + }, + '/Earth' +); + +// Mars +OSCdef.new( + \Mars, + { + arg msg; + + // Follow the planets sonification data map above + // Mars does not have the GUI settings: + // - Rings + // Mars have moon data for 2 moons in the following order: + // - Phobos + // - Deimos + + ("Mars: " + msg).postln; + }, + '/Mars' +); + +// Jupiter +OSCdef.new( + \Jupiter, + { + arg msg; + + // Follow the planets sonification data map above + // Jupiter does not have the GUI settings: + // - Rings (there are rings in real-life, but not in OpenSpace) + // Jupiter have moon data for 4 moons in the following order: + // - Io + // - Europa + // - Ganymede + // - Callisto + + ("Jupiter: " + msg).postln; + }, + '/Jupiter' +); + +// Saturn +OSCdef.new( + \Saturn, + { + arg msg; + + // Follow the planets sonification data map above + // Saturn have moon data for 8 moons in the following order: + // - Dione + // - Enceladus + // - Hyperion + // - Iapetus + // - Mimas + // - Rhea + // - Tethys + // - Titan + + ("Saturn: " + msg).postln; + }, + '/Saturn' +); + +// Uranus +OSCdef.new( + \Uranus, + { + arg msg; + + // Follow the planets sonification data map above + // Uranus does not have the GUI settings: + // - Rings (there are rings in real-life, but not in OpenSpace) + // Uranus have moon data for 5 moons in the following order: + // - Ariel + // - Miranda + // - Oberon + // - Titania + // - Umbriel + + ("Uranus: " + msg).postln; + }, + '/Uranus' +); + +// Neptune +OSCdef.new( + \Neptune, + { + arg msg; + + // Follow the planets sonification data map above + // Neptune does not have the GUI settings: + // - Rings (there are rings in real-life, but not in OpenSpace) + // Neptune have moon data for 2 moons in the following order: + // - Triton + // - Nereid + + ("Neptune: " + msg).postln; + }, + '/Neptune' +); + +) diff --git a/data/assets/examples/sonification/space-station-sonification.scd b/data/assets/examples/sonification/space-station-sonification.scd new file mode 100644 index 0000000000..558d31f32b --- /dev/null +++ b/data/assets/examples/sonification/space-station-sonification.scd @@ -0,0 +1,390 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2025 * + * * + * 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. * + ****************************************************************************************/ + +Platform.userExtensionDir +NetAddr.langPort; +NetAddr.localAddr; + +/***************************************************************************************** + * This is a SuperCollider file that needs to be run in the SuperCollider application * + * that can be downloaded here: https://supercollider.github.io/ * + * * + * This is an example file for the ISS and Tiangong space stations. This sonification * + * will emit an impulse sound for both stations, with Tiangong having a higher pitch and * + * ISS a lower pitch when the camera is close to either of the space stations. For a * + * more extensive example that shows how to create sounds in SuperCollider based on the * + * data from OpenSpace, see the planets-sonification.scd file located in * + * data\assets\modules\telemetry\sonification. This sonification was made by Elias * + * Elmquist. * + * * + * To run a SuperCollider file, click any line within the parentheses below, such as the * + * marked line. When you have selected a line, press the CTRL and ENTER keys on your * + * keyboard at the same time, and SuperCollider will run the code. You will see several * + * messages appear in the log to the right, the last message should be: * + * "---------- Sonification is ready ----------". At this point, SuperCollider is ready * + * to receive messages from OpenSpace and produce the sonification. For a guide on how * + * to enable and use the Telemetry module inside OpenSpace, see this documentation page: * + * https://docs.openspaceproject.com/latest/creating-data-assets/modules/telemetry/ * + * index.html * + ****************************************************************************************/ + +( + +// To run this example, click this line and press CTRL + ENTER on the keyboard +// When finished, press CTRL + . on you keyboard simultaneously to stop the sonification + +s.quit; +o = Server.default.options; + +// TODO Update this to use the angle calculation setting in OpenSpace +// 0: Stereo (Binaurual) +// 1: VisC Dome +// 2: Hayden +~setup = 0; + +if((~setup == 0), + {~numSpeakerChannels = 2;} +); + +if((~setup == 1), + {o.outDevice_("ASIO : Focusrite USB ASIO"); + ~numSpeakerChannels = 8; + } +); + +if((~setup == 2), + {o.outDevice_("ASIO : ASIO MADIface USB"); + ~numSpeakerChannels = 32; + } +); + +o.numOutputBusChannels = ~numSpeakerChannels; + +//3D +~ampMode = 1; +~focusType = 1; +~lockedFocus = 0; +~comparisonMode = 1; + +// Setup which nodes to listen to in OpenSpace +~oscLabel0 = \ISS; +~oscLabel1 = \Tiangong; + +s.reboot; +s.waitForBoot{ + var loadSynths = { + // Create a sound function to play a poof sound + SynthDef( + \synth, + { + arg out=0, gate=1, mamp=5, amp=0, baseAmp=1, freq=400, buf, loop=0, rate=1, da=0, atk=1, dcay=0, suslvl=1, rel=1, mute=1, trig=0, phase=0; + var sig=0, env, t_gate=0; + + t_gate = gate * LFPulse.kr(0.2,phase); + + env = EnvGen.kr( + Env.perc(0.01,1/0.5), + t_gate, + doneAction:0 + ); + + sig = BrownNoise.ar(1); + sig = (BPF.ar(sig, freq*2, 0.004) * 50); + sig = mamp * sig; + sig = mute.lag(5) * (baseAmp*amp) * sig * env; + + Out.ar(out, sig); + } + ).add; + + // Setup Ambisonics + ~order = 2; // set this to the order you want + ~numChannels = ((~order + 1)**2).asInteger; + + // binaural decoder (~numChannels -> 2) - reads from 'bus' and sums into 'out' + SynthDef.new(\binauralDecoder, { | bus, out = 0 | + Out.ar(out, VSTPlugin.ar(In.ar(bus, ~numChannels), 2)); + }).add; + + SynthDef.new(\allraDecoder, { | bus, out = 0 | + Out.ar(out, VSTPlugin.ar(In.ar(bus, ~numChannels), ~numSpeakerChannels)); + }).add; + + // stereo encoder (2 -> ~numChannels) - replaces stereo signal with ambisonics signal + SynthDef.new(\stereoEncoder, { | bus = 0 | + ReplaceOut.ar(bus, VSTPlugin.ar(In.ar(bus, 2), ~numChannels)); + }).add; + + // ambisonics insert FX Surround (replaces input with output) + SynthDef.new(\ambiFX, { | bus = 0, bypass | + ReplaceOut.ar(bus, VSTPlugin.ar(In.ar(bus, ~numChannels), ~numChannels, bypass)); + }).add; + + // helper Synth (throws audio from ambi bus to ambi master bus) + SynthDef.new(\ambiThrow, { | from, to | + Out.ar(to, In.ar(from, ~numChannels)); + }).add; + }; + + + var initiateAmbisonic = { + // bus + group + ~ambiMasterBus = Bus.audio(s, ~numChannels); + ~ambiMasterGroup = Group.new; + + if((~setup == 0), + // binaural decoder (writes to master output) + {~decoder = VSTPluginController(Synth(\binauralDecoder, [\bus, ~ambiMasterBus, \out, 0], target: ~ambiMasterGroup, addAction: \addToTail)).open("BinauralDecoder");}, + // AllRA decoder + {~decoder = VSTPluginController(Synth(\allraDecoder, [\bus, ~ambiMasterBus, \out, 0], target: ~ambiMasterGroup, addAction: \addToTail)).open("SimpleDecoder");} + ); + + // ambisonics insert FX (replaces input with output) + SynthDef.new(\ambiFX, { | bus = 0, bypass | + ReplaceOut.ar(bus, VSTPlugin.ar(In.ar(bus, 2), ~numChannels, bypass)); + }).add; + + // a group for ambisonic master effects + ~ambiMasterFXGroup = Group.before(~decoder.synth); + }; + + var initiateSynths = { + // create ambisonic busses + ~soundBus = Array.newClear(7); + ~numBus = ~soundBus.size; + ~ambiBus = Array.newClear(~numBus); + ~ambiGroup = Array.newClear(~numBus); + ~encoder = Array.newClear(~numBus); + ~sounds = Array.newClear(~numBus); + + // First Poof + ~ambiBus[0] = Bus.audio(s, ~numChannels); + ~ambiGroup[0] = Group.before(~ambiMasterGroup); + ~sounds[0] = Synth.new(\synth, [\out, ~ambiBus[0], \freq, 200], ~ambiGroup[0], addAction: \addToHead); + ~encoder[0] = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBus[0]], target: ~ambiGroup[0], addAction: \addToTail)); + ~encoder[0].open("StereoEncoder", action: { |self| self.set(6, 0.5) }); // 6 -> azimuth + Synth(\ambiThrow, [\from, ~ambiBus[0], \to, ~ambiMasterBus], target: ~ambiGroup[0], addAction: \addToTail); + + // Second Poof + ~ambiBus[1] = Bus.audio(s, ~numChannels); + ~ambiGroup[1] = Group.before(~ambiMasterGroup); + ~sounds[1] = Synth.new(\synth, [\out, ~ambiBus[1], \freq, 400, \phase, 0.3], ~ambiGroup[1], addAction: \addToHead); + ~encoder[1] = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBus[1]], target: ~ambiGroup[1], addAction: \addToTail)); + ~encoder[1].open("StereoEncoder", action: { |self| self.set(6, 0.6) }); // 6 -> azimuth + Synth(\ambiThrow, [\from, ~ambiBus[1], \to, ~ambiMasterBus], target: ~ambiGroup[1], addAction: \addToTail); + + //Audio mixing of the sounds (if needed) + ~sounds[0].set(\baseAmp, 0.3); + ~sounds[1].set(\baseAmp, 0.3); + + // Debugging spatial position + //~encoder[0].editor; + + // add an ambisonic master FX + ~ambiReverb = VSTPluginController(Synth(\ambiFX, [\bus, ~ambiMasterBus, \out, 0], + target: ~ambiMasterFXGroup)).open("FdnReverb", action: { |self| self.set(1, 0.2) }); + }; + + var loadDecoder = { + if((~setup == 1), + { + ~decoder.iemPluginOSC("/SimpleDecoder/loadFile", thisProcess.nowExecutingPath.dirname +/+ "AmbiDecoders" +/+ "DomenVisC_5th.json"); + 0.1.wait; + ~decoder.iemPluginOSC("/SimpleDecoder/swMode", 1); + 0.1.wait; + ~decoder.iemPluginOSC("/SimpleDecoder/swChannel", 4); + 0.1.wait; + ~decoder.iemPluginOSC("/SimpleDecoder/lowPassGain", -12); + } + ); + + if((~setup == 2), + { + ~decoder.iemPluginOSC("/SimpleDecoder/loadFile", thisProcess.nowExecutingPath.dirname +/+ "AmbiDecoders" +/+ "HaydenIEM_5th_0deg_80top_rot180deg.json"); + 0.1.wait; + ~decoder.iemPluginOSC("/SimpleDecoder/swMode", 1); + 0.1.wait; + ~decoder.iemPluginOSC("/SimpleDecoder/swChannel", 32); + 0.1.wait; + } + ); + }; + + // Set which OSC labels to listen to + var oscDef = { + + //Horizontal mode + ~modeElSign = 1; + ~modeElPhase = 0.5; + + //Circular mode (switch manually) + //~modeElSign = -1; + //~modeElPhase = 0.75; + + //Size of hearable area + ~distanceLimit = 10; + + //Ambient amp + ~ambientAmp = 0.1; + + OSCdef.new(\Mode, + { + arg msg; + + //msg[1] == 0 -> Horizontal + //msg[1] == 1 -> Circular + + //msg[2] == 0 -> Elevation on + //msg[2] == 1 -> Elevation off + + ("SurroundMode:" + msg[1]).postln; + + //Horizontal + if(((msg[1]==0)), + {~modeElSign = 1; + ~modeElPhase = 0.5;}, + {} + ); + + //Circular + if(((msg[1]==1)), + {~modeElSign = -1; + ~modeElPhase = 0.75;}, + {} + ); + + ("~modeElSign:" + ~modeElSign).postln; + ("~modeElPhase:" + ~modeElPhase).postln; + + },'/Mode'); + + OSCdef.new( + ~oscLabel0, + { + arg msg; + var name, distance, invDistance, azimuth, amp, value, elevation; + + //msg[1]: label distance + //msg[2]: label azimuth + //msg[3]: label elevation + + // DEBUG: Uncomment this line to get console output of all messages from OpenSpace + //(~oscLabel0 ++ ": " ++ msg).postln; + + name = msg[0].asString; + + distance = msg[1]/1000000; + + //invDistance = ~distanceLimit-distance; + + azimuth = (msg[2]/(2*pi))+0.5; + elevation = ~modeElSign*(msg[3]/(2*pi))+~modeElPhase; + + if((~ampMode == 1), + { + if((distance < ~distanceLimit), + {amp = LinLin.kr(distance, 0, ~distanceLimit, 0, 1); + + }, + {amp = ~ambientAmp;} + ); + } + ); + + (~oscLabel0 ++ "Amp: " ++ amp).postln; + ~sounds[0].set(\amp, amp); + ~encoder[0].do(_.set(6, azimuth)); + ~encoder[0].do(_.set(7, elevation)); + }, + ~oscLabel0 + ); + + OSCdef.new( + ~oscLabel1, + { + arg msg; + var name, distance, invDistance, azimuth, amp, value, elevation; + + //msg[1]: label distance + //msg[2]: label azimuth + //msg[3]: label elevation + + // DEBUG: Uncomment this line to get console output of messages from OpenSpace + //(~oscLabel1 ++ ": " ++ msg).postln; + + name = msg[0].asString; + + distance = msg[1]/10000; + + //invDistance = ~distanceLimit-distance; + + azimuth = (msg[2]/(2*pi))+0.5; + elevation = ~modeElSign*(msg[3]/(2*pi))+~modeElPhase; + + if((~ampMode == 1), + { + if((distance < ~distanceLimit), + {amp = LinLin.kr(distance, 0, ~distanceLimit, 0, 1); + + }, + {amp = ~ambientAmp;} + ); + } + ); + + (~oscLabel1 ++ "Amp: " ++ amp).postln; + ~sounds[1].set(\amp, amp); + ~encoder[1].do(_.set(6, azimuth)); + ~encoder[1].do(_.set(7, elevation)); + + }, + ~oscLabel1 + ); + + }; + + // Start routine + ~startRoutine = Routine({ + 0.5.wait; + loadSynths.value; + "--Loaded the synths--".postln; + 0.3.wait; + initiateAmbisonic.value; + "--Loaded the ambisonics--".postln; + 0.3.wait; + initiateSynths.value; + "--Initiated the synths--".postln; + 0.2.wait; + loadDecoder.value; + "--Loaded the decoder--".postln; + 0.2.wait; + oscDef.value; + "--Loaded the OSCdefs--".postln; + "---------- Sonification is ready ----------".postln; + }); + + ~startRoutine.play(AppClock); +} + +) diff --git a/data/assets/examples/sonification/voyager-sonification.scd b/data/assets/examples/sonification/voyager-sonification.scd new file mode 100644 index 0000000000..8a7f590389 --- /dev/null +++ b/data/assets/examples/sonification/voyager-sonification.scd @@ -0,0 +1,402 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2025 * + * * + * 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. * + ****************************************************************************************/ + +Platform.userExtensionDir +NetAddr.langPort; +NetAddr.localAddr; + +/***************************************************************************************** + * This is a SuperCollider file that needs to be run in the SuperCollider application * + * that can be downloaded here: https://supercollider.github.io/ * + * * + * This is an example file for the Voyager 1 and 2 space probes. This sonification will * + * play and loop the Greetings to the Universe audio clip (one of the recordings * + * included on the Golden Records aboard both probes) when the camera is close to either * + * of the probes. For a more extensive example that shows how to create sounds in * + * SuperCollider based on the data from OpenSpace, see the planets-sonification.scd file * + * located in data\assets\modules\telemetry\sonification. This sonification was made by * + * Elias Elmquist. * + * * + * To run a SuperCollider file, click any line within the parentheses below, such as the * + * marked line. When you have selected a line, press the CTRL and ENTER keys on your * + * keyboard at the same time, and SuperCollider will run the code. You will see several * + * messages appear in the log to the right, the last message should be: * + * "---------- Sonification is ready ----------". At this point, SuperCollider is ready * + * to receive messages from OpenSpace and produce the sonification. For a guide on how * + * to enable and use the Telemetry module inside OpenSpace, see the documentation page: * + * https://docs.openspaceproject.com/latest/creating-data-assets/modules/telemetry/ * + * index.html * + ****************************************************************************************/ + +( + +// To run this example, click this line and press CTRL + ENTER on the keyboard +// When finished, press CTRL + . on you keyboard simultaneously to stop the sonification + +s.quit; +o = Server.default.options; + +// TODO Update this to use the angle calculation setting in OpenSpace +// Set the surround setting +// 0: Stereo (Binaurual) +// 1: VisC Dome +// 2: Hayden +~setup = 0; + +if((~setup == 0), + {~numSpeakerChannels = 2;} +); + +if((~setup == 1), + {o.outDevice_("ASIO : Focusrite USB ASIO"); + ~numSpeakerChannels = 8; + } +); + +if((~setup == 2), + {o.outDevice_("ASIO : ASIO MADIface USB"); + ~numSpeakerChannels = 32; + } +); + +o.numOutputBusChannels = ~numSpeakerChannels; + +//3D +~ampMode = 1; +~focusType = 1; +~lockedFocus = 0; +~comparisonMode = 1; + +// Setup which nodes to listen to in OpenSpace +~oscLabel0 = \Voyager_1; +~oscLabel1 = \Voyager_2; + +s.reboot; +s.waitForBoot{ + // Load the Greetings to the Universe audio clip (located next to this file) + var filePath = thisProcess.nowExecutingPath.dirname; + var loadSamples = { + ~b1 = Buffer.read(s, filePath +/+ "Greetings_from_Earth_mono.wav"); + // To load another audio clip, copy the line above, change the variable name + // and the path to the audio file + }; + + var loadSynths = { + // Create a sound function to play and loop the audio clip + SynthDef( + \audiofile, + { + arg out=0, gate=1, mamp=5, amp=0, baseAmp=1, buf, loop=0, rate=1, da=0, atk=1, dcay=0, suslvl=1, rel=1, mute=1, trig=0; + var sig=0, env; + + env = EnvGen.kr( + Env.adsr(atk,dcay,suslvl,rel), + gate, + doneAction:da + ); + + sig = PlayBuf.ar(1, buf, rate:rate, loop:loop, trigger:trig); + sig = mamp * sig; + sig = mute.lag(5) * (baseAmp*amp) * sig * env; + + Out.ar(out, sig); + } + ).add; + + + // Setup Ambisonics + ~order = 2; // set this to the order you want + ~numChannels = ((~order + 1)**2).asInteger; + + // binaural decoder (~numChannels -> 2) - reads from 'bus' and sums into 'out' + SynthDef.new(\binauralDecoder, { | bus, out = 0 | + Out.ar(out, VSTPlugin.ar(In.ar(bus, ~numChannels), 2)); + }).add; + + SynthDef.new(\allraDecoder, { | bus, out = 0 | + Out.ar(out, VSTPlugin.ar(In.ar(bus, ~numChannels), ~numSpeakerChannels)); + }).add; + + // stereo encoder (2 -> ~numChannels) - replaces stereo signal with ambisonics signal + SynthDef.new(\stereoEncoder, { | bus = 0 | + ReplaceOut.ar(bus, VSTPlugin.ar(In.ar(bus, 2), ~numChannels)); + }).add; + + // ambisonics insert FX Surround (replaces input with output) + SynthDef.new(\ambiFX, { | bus = 0, bypass | + ReplaceOut.ar(bus, VSTPlugin.ar(In.ar(bus, ~numChannels), ~numChannels, bypass)); + }).add; + + // helper Synth (throws audio from ambi bus to ambi master bus) + SynthDef.new(\ambiThrow, { | from, to | + Out.ar(to, In.ar(from, ~numChannels)); + }).add; + }; + + var initiateAmbisonic = { + // bus + group + ~ambiMasterBus = Bus.audio(s, ~numChannels); + ~ambiMasterGroup = Group.new; + + if((~setup == 0), + // binaural decoder (writes to master output) + {~decoder = VSTPluginController(Synth(\binauralDecoder, [\bus, ~ambiMasterBus, \out, 0], target: ~ambiMasterGroup, addAction: \addToTail)).open("BinauralDecoder");}, + // AllRA decoder + {~decoder = VSTPluginController(Synth(\allraDecoder, [\bus, ~ambiMasterBus, \out, 0], target: ~ambiMasterGroup, addAction: \addToTail)).open("SimpleDecoder");} + ); + + // ambisonics insert FX (replaces input with output) + SynthDef.new(\ambiFX, { | bus = 0, bypass | + ReplaceOut.ar(bus, VSTPlugin.ar(In.ar(bus, 2), ~numChannels, bypass)); + }).add; + + // a group for ambisonic master effects + ~ambiMasterFXGroup = Group.before(~decoder.synth); + }; + + var initiateSynths = { + // create ambisonic busses + ~soundBus = Array.newClear(7); + ~numBus = ~soundBus.size; + ~ambiBus = Array.newClear(~numBus); + ~ambiGroup = Array.newClear(~numBus); + ~encoder = Array.newClear(~numBus); + ~sounds = Array.newClear(~numBus); + + // First Audio clip + ~ambiBus[0] = Bus.audio(s, ~numChannels); + ~ambiGroup[0] = Group.before(~ambiMasterGroup); + ~sounds[0] = Synth.new(\audiofile, [\out, ~ambiBus[0], \buf, ~b1], ~ambiGroup[0], addAction: \addToHead); + ~encoder[0] = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBus[0]], target: ~ambiGroup[0], addAction: \addToTail)); + ~encoder[0].open("StereoEncoder", action: { |self| self.set(6, 0.5) }); // 6 -> azimuth + Synth(\ambiThrow, [\from, ~ambiBus[0], \to, ~ambiMasterBus], target: ~ambiGroup[0], addAction: \addToTail); + + // Second Audio clip (if needed) + /*~ambiBus[1] = Bus.audio(s, ~numChannels); + ~ambiGroup[1] = Group.before(~ambiMasterGroup); + ~sounds[1] = Synth.new(\audiofile, [\out, ~ambiBus[1], \buf, ~b2], ~ambiGroup[1], addAction: \addToHead); + ~encoder[1] = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBus[1]], target: ~ambiGroup[1], addAction: \addToTail)); + ~encoder[1].open("StereoEncoder", action: { |self| self.set(6, 0.6) }); // 6 -> azimuth + Synth(\ambiThrow, [\from, ~ambiBus[1], \to, ~ambiMasterBus], target: ~ambiGroup[1], addAction: \addToTail); + + //Audio mixing of the sounds (if needed) + ~sounds[0].set(\baseAmp, 0.3); + ~sounds[1].set(\baseAmp, 0.3);*/ + + // Debugging spatial position + //~encoder[0].editor; + + ~sounds[0].set(\baseAmp, 0.3); + + // add an ambisonic master FX + ~ambiReverb = VSTPluginController(Synth(\ambiFX, [\bus, ~ambiMasterBus, \out, 0], + target: ~ambiMasterFXGroup)).open("FdnReverb", action: { |self| self.set(1, 0.2) }); + + }; + + var loadDecoder = { + if((~setup == 1), + { + ~decoder.iemPluginOSC("/SimpleDecoder/loadFile", thisProcess.nowExecutingPath.dirname +/+ "AmbiDecoders" +/+ "DomenVisC_5th.json"); + 0.1.wait; + ~decoder.iemPluginOSC("/SimpleDecoder/swMode", 1); + 0.1.wait; + ~decoder.iemPluginOSC("/SimpleDecoder/swChannel", 4); + 0.1.wait; + ~decoder.iemPluginOSC("/SimpleDecoder/lowPassGain", -12); + } + ); + + if((~setup == 2), + { + ~decoder.iemPluginOSC("/SimpleDecoder/loadFile", thisProcess.nowExecutingPath.dirname +/+ "AmbiDecoders" +/+ "HaydenIEM_5th_0deg_80top_rot180deg.json"); + 0.1.wait; + ~decoder.iemPluginOSC("/SimpleDecoder/swMode", 1); + 0.1.wait; + ~decoder.iemPluginOSC("/SimpleDecoder/swChannel", 32); + 0.1.wait; + } + ); + }; + + // Set which OSC labels to listen to + var oscDef = { + + + //Horizontal mode + ~modeElSign = 1; + ~modeElPhase = 0.5; + + //Circular mode (switch manually) + //~modeElSign = -1; + //~modeElPhase = 0.75; + + //Size of hearable area + ~distanceLimit = 0.5; + + //Ambient amp + ~ambientAmp = 0.1; + + OSCdef.new(\Mode, + { + arg msg; + + //msg[1] == 0 -> Horizontal + //msg[1] == 1 -> Circular + + //msg[2] == 0 -> Elevation on + //msg[2] == 1 -> Elevation off + + ("SurroundMode:" + msg[1]).postln; + + //Horizontal + if(((msg[1]==0)), + {~modeElSign = 1; + ~modeElPhase = 0.5;}, + {} + ); + + //Circular + if(((msg[1]==1)), + {~modeElSign = -1; + ~modeElPhase = 0.75;}, + {} + ); + + ("~modeElSign:" + ~modeElSign).postln; + ("~modeElPhase:" + ~modeElPhase).postln; + + },'/Mode'); + + OSCdef.new( + ~oscLabel0, + { + arg msg; + var name, distance, invDistance, azimuth, amp, value, elevation; + + //msg[1]: label distance + //msg[2]: label azimuth + //msg[3]: label elevation + + // DEBUG: Uncomment this line to get console output of all messages from OpenSpace + //(~oscLabel0 ++ ": " ++ msg).postln; + + name = msg[0].asString; + + distance = msg[1]/1000000; + + //invDistance = ~distanceLimit-distance; + + azimuth = (msg[2]/(2*pi))+0.5; + elevation = ~modeElSign*(msg[3]/(2*pi))+~modeElPhase; + + if((~ampMode == 1), + { + if((distance < ~distanceLimit), + {amp = LinLin.kr(distance, 0, ~distanceLimit, 0, 1); + + }, + {amp = ~ambientAmp;} + ); + } + ); + + (~oscLabel0 ++ "Amp: " ++ amp).postln; + ~sounds[0].set(\amp, amp); + ~encoder[0].do(_.set(6, azimuth)); + ~encoder[0].do(_.set(7, elevation)); + }, + ~oscLabel0 + ); + + OSCdef.new( + ~oscLabel1, + { + arg msg; + var name, distance, invDistance, azimuth, amp, value, elevation; + + //msg[1]: label distance + //msg[2]: label azimuth + //msg[3]: label elevation + + // DEBUG: Uncomment this line to get console output of all messages from OpenSpace + //(~oscLabel1 ++ ": " ++ msg).postln; + + name = msg[0].asString; + + distance = msg[1]/1000000; + + //invDistance = ~distanceLimit-distance; + + azimuth = (msg[2]/(2*pi))+0.5; + elevation = ~modeElSign*(msg[3]/(2*pi))+~modeElPhase; + + if((~ampMode == 1), + { + if((distance < ~distanceLimit), + {amp = LinLin.kr(distance, 0, ~distanceLimit, 0, 1); + + }, + {amp = ~ambientAmp;} + ); + } + ); + + (~oscLabel1 ++ "Amp: " ++ amp).postln; + ~sounds[0].set(\amp, amp); + ~encoder[0].do(_.set(6, azimuth)); + ~encoder[0].do(_.set(7, elevation)); + }, + ~oscLabel1 + ); + + }; + + // Start routine + ~startRoutine = Routine({ + 0.5.wait; + loadSamples.value; + "--Loaded the data--".postln; + 0.2.wait; + loadSynths.value; + "--Loaded the synths--".postln; + 0.3.wait; + initiateAmbisonic.value; + "--Loaded the ambisonics--".postln; + 0.3.wait; + initiateSynths.value; + "--Initiated the synths--".postln; + 0.2.wait; + loadDecoder.value; + "--Loaded the decoder--".postln; + 0.2.wait; + oscDef.value; + "--Loaded the OSCdefs--".postln; + "---------- Sonification is ready ----------".postln; + }); + + ~startRoutine.play(AppClock); +} + +) diff --git a/data/assets/examples/timeframe/timeframeinterval/interval.asset b/data/assets/examples/timeframe/timeframeinterval/interval.asset new file mode 100644 index 0000000000..acfb800eb5 --- /dev/null +++ b/data/assets/examples/timeframe/timeframeinterval/interval.asset @@ -0,0 +1,28 @@ +-- Basic +-- This example creates time frame interval and uses it for a scene graph node displaying +-- a set of coordinate axes. The time frame interval causes the scene graph node to only +-- be valid between January 1st, 2000 and March 1st, 2002. + +local Node = { + Identifier = "TimeFrameInterval_Example", + TimeFrame = { + Type = "TimeFrameInterval", + Start = "2000 JAN 01 00:00:00.000", + End = "2002 MAR 02 00:00:00.00" + }, + Renderable = { + Type = "RenderableCartesianAxes" + }, + GUI = { + Name = "TimeFrameInterval - Basic", + Path = "/Examples" + } +} + +asset.onInitialize(function() + openspace.addSceneGraphNode(Node) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(Node) +end) diff --git a/data/assets/examples/timeframe/timeframekernel/kernel_ck-multiple.asset b/data/assets/examples/timeframe/timeframekernel/kernel_ck-multiple.asset new file mode 100644 index 0000000000..c8e27a403b --- /dev/null +++ b/data/assets/examples/timeframe/timeframekernel/kernel_ck-multiple.asset @@ -0,0 +1,44 @@ +-- CK Multiple +-- This example creates a time frame based on the information provided by multiple SPICE +-- kernel files that contain orientation information about the same object. The created +-- scene graph node will only be valid whenever any window in any of the provided kernels +-- contains information about refernence frame "-98000", which is the intertial +-- orientation frame for the New Horizons spacecraft. + +-- We need a SPICE kernel to work with in this example +local data = asset.resource({ + Name = "New Horizons Kernels", + Type = "HttpSynchronization", + Identifier = "newhorizons_kernels", + Version = 1 +}) + +local Node = { + Identifier = "TimeFrameKernel_Example_CK_Multiple", + TimeFrame = { + Type = "TimeFrameKernel", + CK = { + Kernels = { + data .. "nh_apf_20150404_20150420_001.bc", + data .. "nh_apf_20150420_20150504_001.bc", + data .. "new-horizons_1121.tsc" + }, + Reference = "-98000" + } + }, + Renderable = { + Type = "RenderableCartesianAxes" + }, + GUI = { + Name = "TimeFrameKernel - Basic (CK, Multiple)", + Path = "/Examples" + } +} + +asset.onInitialize(function() + openspace.addSceneGraphNode(Node) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(Node) +end) diff --git a/data/assets/examples/timeframe/timeframekernel/kernel_ck.asset b/data/assets/examples/timeframe/timeframekernel/kernel_ck.asset new file mode 100644 index 0000000000..c9354830e9 --- /dev/null +++ b/data/assets/examples/timeframe/timeframekernel/kernel_ck.asset @@ -0,0 +1,42 @@ +-- CK Basic +-- This example creates a time frame based on the information provided by a single SPICE +-- kernel file. The created scene graph node will only be valid whenever the provided +-- kernel contains information about about the reference frame "-98000", which is the +-- interial orientation frame for the New Horizons spacecraft. + +-- We need a SPICE kernel to work with in this example +local data = asset.resource({ + Name = "New Horizons Kernels", + Type = "HttpSynchronization", + Identifier = "newhorizons_kernels", + Version = 1 +}) + +local Node = { + Identifier = "TimeFrameKernel_Example_CK", + TimeFrame = { + Type = "TimeFrameKernel", + CK = { + Kernels = { + data .. "nh_apf_20150404_20150420_001.bc", + data .. "new-horizons_1121.tsc", + }, + Reference = "-98000" + } + }, + Renderable = { + Type = "RenderableCartesianAxes" + }, + GUI = { + Name = "TimeFrameKernel - Basic (CK)", + Path = "/Examples" + } +} + +asset.onInitialize(function() + openspace.addSceneGraphNode(Node) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(Node) +end) diff --git a/data/assets/examples/timeframe/timeframekernel/kernel_spk-ck.asset b/data/assets/examples/timeframe/timeframekernel/kernel_spk-ck.asset new file mode 100644 index 0000000000..87547dc032 --- /dev/null +++ b/data/assets/examples/timeframe/timeframekernel/kernel_spk-ck.asset @@ -0,0 +1,48 @@ +-- Combined example +-- This example creates a time frame based on the information provided by multiple SPICE +-- kernel files. The created scene graph node will only be valid whenever the provided +-- kernels contain information positional information about the object "JUICE" as well as +-- orientation information for the reference frame "-28002" which is the measured attitude +-- for the JUICE spacecraft. The time frame will only be valid if both pieces of data are +-- available. + +-- We need a SPICE kernel to work with in this example +local data = asset.resource({ + Name = "JUICE Kernels", + Type = "HttpSynchronization", + Identifier = "juice_kernels", + Version = 2 +}) + +local Node = { + Identifier = "TimeFrameKernel_Example_Combined_SPK-CK", + TimeFrame = { + Type = "TimeFrameKernel", + SPK = { + Kernels = data .. "juice_orbc_000031_230414_310721_v03.bsp", + Object = "JUICE" + }, + CK = { + Kernels = { + data .. "juice_sc_meas_230413_230415_s230414_v01.bc", + data .. "juice_step_230414_v01.tsc" + }, + Reference = "-28002" + } + }, + Renderable = { + Type = "RenderableCartesianAxes" + }, + GUI = { + Name = "TimeFrameKernel - Combined (SPK+CK)", + Path = "/Examples" + } +} + +asset.onInitialize(function() + openspace.addSceneGraphNode(Node) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(Node) +end) diff --git a/data/assets/examples/timeframe/timeframekernel/kernel_spk-multiple.asset b/data/assets/examples/timeframe/timeframekernel/kernel_spk-multiple.asset new file mode 100644 index 0000000000..9425d231ad --- /dev/null +++ b/data/assets/examples/timeframe/timeframekernel/kernel_spk-multiple.asset @@ -0,0 +1,42 @@ +-- SPK Multiple +-- This example creates a time frame based on the information provided by multiple SPICE +-- kernel files that contain position information about the same object. The created scene +-- graph node will only be valid whenever any window in any of the provided kernels +-- contains information about object "VOYAGER 1". + +-- We need a SPICE kernel to work with in this example +local data = asset.resource({ + Name = "Voyager 1 Kernels", + Type = "HttpSynchronization", + Identifier = "voyager1_spice", + Version = 2 +}) + +local Node = { + Identifier = "TimeFrameKernel_Example_SPK_Multiple", + TimeFrame = { + Type = "TimeFrameKernel", + SPK = { + Kernels = { + data .. "vgr1_jup230.bsp", + data .. "vgr1_sat337.bsp" + }, + Object = "VOYAGER 1" + } + }, + Renderable = { + Type = "RenderableCartesianAxes" + }, + GUI = { + Name = "TimeFrameKernel - Basic (SPK, Multiple)", + Path = "/Examples" + } +} + +asset.onInitialize(function() + openspace.addSceneGraphNode(Node) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(Node) +end) diff --git a/data/assets/examples/timeframe/timeframekernel/kernel_spk.asset b/data/assets/examples/timeframe/timeframekernel/kernel_spk.asset new file mode 100644 index 0000000000..f77fccf4e7 --- /dev/null +++ b/data/assets/examples/timeframe/timeframekernel/kernel_spk.asset @@ -0,0 +1,40 @@ +-- SPK Basic +-- This example creates a time frame based on the information provided by a single SPICE +-- kernel file. The created scene graph node will only be valid whenever the provided +-- kernel contains information about object "-915", which is Apollo 15. In this specific +-- case, the Apollo15 kernel contains two windows of valid data, both of which are used by +-- this time frame. + +-- We need a SPICE kernel to work with in this example +local data = asset.resource({ + Name = "Apollo Kernels", + Type = "HttpSynchronization", + Identifier = "apollo_spice", + Version = 1 +}) + +local Node = { + Identifier = "TimeFrameKernel_Example_SPK", + TimeFrame = { + Type = "TimeFrameKernel", + SPK = { + Kernels = data .. "apollo15-1.bsp", + Object = "-915" + } + }, + Renderable = { + Type = "RenderableCartesianAxes" + }, + GUI = { + Name = "TimeFrameKernel - Basic (SPK)", + Path = "/Examples" + } +} + +asset.onInitialize(function() + openspace.addSceneGraphNode(Node) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(Node) +end) diff --git a/data/assets/examples/timeframe/union.asset b/data/assets/examples/timeframe/timeframeunion/union.asset similarity index 92% rename from data/assets/examples/timeframe/union.asset rename to data/assets/examples/timeframe/timeframeunion/union.asset index f1fa1bd62b..2b4014a90e 100644 --- a/data/assets/examples/timeframe/union.asset +++ b/data/assets/examples/timeframe/timeframeunion/union.asset @@ -13,13 +13,13 @@ local Node = { { Type = "TimeFrameInterval", Start = "2000 JAN 01 00:00:00.000", - End = "2000 JAN 01 23:59:59.999" + End = "2000 JAN 02 00:00:00.000" }, -- The second TimeFrameInterval for the second day { Type = "TimeFrameInterval", Start = "2002 MAR 01 00:00:00.000", - End = "2002 MAR 01 23:59:59.999" + End = "2002 MAR 02 00:00:00.000" } } }, diff --git a/data/assets/examples/translation/luatranslation/lua.asset b/data/assets/examples/translation/luatranslation/lua.asset index 722b8f1830..bf14caa61d 100644 --- a/data/assets/examples/translation/luatranslation/lua.asset +++ b/data/assets/examples/translation/luatranslation/lua.asset @@ -1,8 +1,9 @@ -- Basic --- This asset creates a SceneGraphNode that only displays coordinate axes. The coordinate --- axes are translated by a value determined by executing a Lua file that returns the --- translation parameters to be used as a table. In order to see the translation, we need --- to also have a node that does not move so that we can see the relative movement. +-- This asset creates a scene graph node that only displays coordinate axes. The +-- coordinate axes are translated by a value determined by executing a Lua file that +-- returns the translation parameters to be used as a table. In order to see the +-- translation, we need to also have a node that does not move so that we can see the +-- relative movement. -- -- ```{literalinclude} example.lua -- :language: lua diff --git a/data/assets/examples/translation/spicetranslation/spice.asset b/data/assets/examples/translation/spicetranslation/spice.asset index 49b33775e5..3a2cd972b1 100644 --- a/data/assets/examples/translation/spicetranslation/spice.asset +++ b/data/assets/examples/translation/spicetranslation/spice.asset @@ -1,7 +1,7 @@ -- Basic -- This asset creates a time-varying translation with information from a SPICE kernel and --- applies it to a SceneGraphNode that only displays coordinate axes. The position of the --- coordinate axes are determined by SPICE, in this case pretending that the axes are +-- applies it to a scene graph node that only displays coordinate axes. The position of +-- the coordinate axes are determined by SPICE, in this case pretending that the axes are -- orbiting the same way the Moon does around Earth. -- For more information about SPICE see: https://naif.jpl.nasa.gov/naif/ diff --git a/data/assets/examples/translation/spicetranslation/fixeddate.asset b/data/assets/examples/translation/spicetranslation/spice_fixeddate.asset similarity index 85% rename from data/assets/examples/translation/spicetranslation/fixeddate.asset rename to data/assets/examples/translation/spicetranslation/spice_fixeddate.asset index 93285faa76..f7a5b93efa 100644 --- a/data/assets/examples/translation/spicetranslation/fixeddate.asset +++ b/data/assets/examples/translation/spicetranslation/spice_fixeddate.asset @@ -1,7 +1,7 @@ -- Fixed Date -- This asset creates a time-varying translation with information from a SPICE kernel and --- applies it to a SceneGraphNode that only displays coordinate axes. The position of the --- coordinate axes are determined by SPICE, in this case pretending that the axes are +-- applies it to a scene graph node that only displays coordinate axes. The position of +-- the coordinate axes are determined by SPICE, in this case pretending that the axes are -- orbiting the same way the Moon does around Earth. In this specific example, the -- position is independent of the actual in-game time in OpenSpace and only uses a fixed -- date of 2000 JAN 01 instead. diff --git a/data/assets/examples/translation/spicetranslation/referenceframe.asset b/data/assets/examples/translation/spicetranslation/spice_referenceframe.asset similarity index 84% rename from data/assets/examples/translation/spicetranslation/referenceframe.asset rename to data/assets/examples/translation/spicetranslation/spice_referenceframe.asset index cb16f29b19..e74df0da07 100644 --- a/data/assets/examples/translation/spicetranslation/referenceframe.asset +++ b/data/assets/examples/translation/spicetranslation/spice_referenceframe.asset @@ -1,7 +1,7 @@ -- Reference Frame -- This asset creates a time-varying translation with information from a SPICE kernel and --- applies it to a SceneGraphNode that only displays coordinate axes. The position of the --- coordinate axes are determined by SPICE, in this case pretending that the axes are +-- applies it to a scene graph node that only displays coordinate axes. The position of +-- the coordinate axes are determined by SPICE, in this case pretending that the axes are -- orbiting the same way the Moon does around Earth. The calculated position will be -- provided in the rotating coordinate system of Earth itself. -- For more information about SPICE see: https://naif.jpl.nasa.gov/naif/ diff --git a/data/assets/examples/translation/spicetranslation/timeoffset.asset b/data/assets/examples/translation/spicetranslation/spice_timeoffset.asset similarity index 84% rename from data/assets/examples/translation/spicetranslation/timeoffset.asset rename to data/assets/examples/translation/spicetranslation/spice_timeoffset.asset index 1e557447f9..e5170fc2d7 100644 --- a/data/assets/examples/translation/spicetranslation/timeoffset.asset +++ b/data/assets/examples/translation/spicetranslation/spice_timeoffset.asset @@ -1,7 +1,7 @@ -- Fixed Date -- This asset creates a time-varying translation with information from a SPICE kernel and --- applies it to a SceneGraphNode that only displays coordinate axes. The position of the --- coordinate axes are determined by SPICE, in this case pretending that the axes are +-- applies it to a scene graph node that only displays coordinate axes. The position of +-- the coordinate axes are determined by SPICE, in this case pretending that the axes are -- orbiting the same way the Moon does around Earth. In this specific example, the position -- is offset 8h back compared to the actual in-game time in OpenSpace. -- For more information about SPICE see: https://naif.jpl.nasa.gov/naif/ diff --git a/data/assets/examples/translation/timelinetranslation/timeline.asset b/data/assets/examples/translation/timelinetranslation/timeline.asset new file mode 100644 index 0000000000..d7151a9c92 --- /dev/null +++ b/data/assets/examples/translation/timelinetranslation/timeline.asset @@ -0,0 +1,48 @@ +-- Basic +-- This asset creates a scene graph node that only displays coordinate axes whose +-- translation of the coordinate axes is determined by a timeline of individual +-- translations. These translations are provided as keyframes that interpolate seamlessly +-- between different positions. +-- +-- This example will only work if the in-game time is set to January 1st, 2000. + +local Node = { + Identifier = "TimelineTranslation_Example", + Transform = { + Translation = { + Type = "TimelineTranslation", + Keyframes = { + -- The first timeline entry + ["2000 JAN 01 00:00:00"] = { + Type = "StaticTranslation", + Position = { -10.0, 0.0, 0.0 } + }, + -- The second timeline entry + ["2000 JAN 01 12:00:00"] = { + Type = "StaticTranslation", + Position = { 0.0, 0.0, 0.0 } + }, + -- The third timeline entry + ["2000 JAN 01 23:59:59"] = { + Type = "StaticTranslation", + Position = { 10.0, 0.0, 0.0 } + } + } + } + }, + Renderable = { + Type = "RenderableCartesianAxes" + }, + GUI = { + Name = "TimelineTranslation - Basic", + Path = "/Examples" + } +} + +asset.onInitialize(function() + openspace.addSceneGraphNode(Node) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(Node) +end) diff --git a/data/assets/examples/translation/timelinetranslation/timeline_no-interpolate.asset b/data/assets/examples/translation/timelinetranslation/timeline_no-interpolate.asset new file mode 100644 index 0000000000..0a8b05609f --- /dev/null +++ b/data/assets/examples/translation/timelinetranslation/timeline_no-interpolate.asset @@ -0,0 +1,55 @@ +-- No Interpolation +-- This asset creates a scene graph node that only displays coordinate axes whose +-- translation of the coordinate axes is determined by a timeline of individual +-- translations that are used without interpolating between the timeline entries. These +-- translations are keyframes that are used to change between different positions. +-- +-- This example transitions between three positions. In this example, the interpolation +-- between entries is disabled, which will cause the coordinate axes to change their +-- position abruptly when the translation changes. If the interpolation were enabled, the +-- orientation of the coordinate axes would transition seamlessly instead at the provided +-- times. +-- +-- This example will only work if the in-game time is set to January 1st, 2000. + +local Node = { + Identifier = "TimelineTranslation_Example_NoInterpolation", + Transform = { + Translation = { + Type = "TimelineTranslation", + Keyframes = { + -- The first timeline entry + ["2000 JAN 01 00:00:00"] = { + Type = "StaticTranslation", + Position = { -10.0, 0.0, 0.0 } + }, + -- The second timeline entry + ["2000 JAN 01 12:00:00"] = { + Type = "StaticTranslation", + Position = { 0.0, 0.0, 0.0 } + }, + -- The third timeline entry + ["2000 JAN 01 23:59:59"] = { + Type = "StaticTranslation", + Position = { 10.0, 0.0, 0.0 } + } + }, + ShouldInterpolate = false + } + }, + Renderable = { + Type = "RenderableCartesianAxes" + }, + GUI = { + Name = "TimelineTranslation - No Interpolation", + Path = "/Examples" + } +} + +asset.onInitialize(function() + openspace.addSceneGraphNode(Node) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(Node) +end) diff --git a/data/assets/modules/exoplanets/default_settings.asset b/data/assets/modules/exoplanets/default_settings.asset index 3684d9742c..684f1d465a 100644 --- a/data/assets/modules/exoplanets/default_settings.asset +++ b/data/assets/modules/exoplanets/default_settings.asset @@ -1,5 +1,4 @@ asset.onInitialize(function() - openspace.setPropertyValueSingle("Modules.Exoplanets.Enabled", true) openspace.setPropertyValueSingle("Modules.Exoplanets.ShowComparisonCircle", false) openspace.setPropertyValueSingle("Modules.Exoplanets.ShowHabitableZone", true) openspace.setPropertyValueSingle("Modules.Exoplanets.UseOptimisticZone", true) diff --git a/data/assets/modules/exoplanets/exoplanets_data.asset b/data/assets/modules/exoplanets/exoplanets_data.asset index 7bf8632d35..31a17c2a37 100644 --- a/data/assets/modules/exoplanets/exoplanets_data.asset +++ b/data/assets/modules/exoplanets/exoplanets_data.asset @@ -2,7 +2,7 @@ local dataPath = asset.resource({ Name = "Exoplanet Data Files", Type = "HttpSynchronization", Identifier = "exoplanets_data", - Version = 6 + Version = 7 }) local colormaps = asset.resource({ diff --git a/data/assets/modules/skybrowser/default_settings.asset b/data/assets/modules/skybrowser/default_settings.asset deleted file mode 100644 index ceb952e9ec..0000000000 --- a/data/assets/modules/skybrowser/default_settings.asset +++ /dev/null @@ -1,15 +0,0 @@ -asset.onInitialize(function() - openspace.setPropertyValueSingle("Modules.SkyBrowser.Enabled", true) - openspace.setPropertyValueSingle("Modules.SkyBrowser.ShowTitleInGuiBrowser", false) - -- More settings are available, but for now using the default values -end) - - - -asset.meta = { - Name = "SkyBrowser Module Default Settings", - Description = "Some default settings related to the SkyBrowser module", - Author = "OpenSpace Team", - URL = "http://openspaceproject.com", - License = "MIT license" -} diff --git a/data/assets/modules/skybrowser/skybrowser.asset b/data/assets/modules/skybrowser/skybrowser.asset index 4a1db6d382..81214b80cf 100644 --- a/data/assets/modules/skybrowser/skybrowser.asset +++ b/data/assets/modules/skybrowser/skybrowser.asset @@ -1,2 +1 @@ -asset.require("./default_settings") asset.require("./hover_circle") diff --git a/data/assets/modules/telemetry/sonification/planets-sonification.scd b/data/assets/modules/telemetry/sonification/planets-sonification.scd new file mode 100644 index 0000000000..6bf4780b9d --- /dev/null +++ b/data/assets/modules/telemetry/sonification/planets-sonification.scd @@ -0,0 +1,1940 @@ +/***************************************************************************************** +* * +* OpenSpace * +* * +* Copyright (c) 2014-2025 * +* * +* 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. * +****************************************************************************************/ + +Platform.userExtensionDir +NetAddr.langPort; +NetAddr.localAddr; + +/***************************************************************************************** +* This is a SuperCollider file that needs to be run in the SuperCollider application * +* that can be downloaded here: https://supercollider.github.io/ * +* * +* This is a sonification of the planets in the solar system, for more details, see the * +* http://dx.doi.org/10.21785/icad2021.018. This sonification was made by Elias * +* Elmquist. +* * +* To run a SuperCollider file, click any line within the parentheses below, such as the * +* marked line. When you have selected a line, press the CTRL and ENTER keys on your * +* keyboard at the same time, and SuperCollider will run the code. You will see a * +* message appear in the log to the right, the message should be: * +* "-> OSCdef(Neptune, /Neptune, nil, nil, nil)". At this point, SuperCollider is ready * +* to receive messages from OpenSpace. For a guide on how to enable and use the * +* Telemetry module inside OpenSpace, see this documentation page: * +* https://docs.openspaceproject.com/latest/creating-data-assets/modules/telemetry/ * +* index.html * +****************************************************************************************/ + +( + +//Requirements: +// * VST plugin: https://git.iem.at/pd/vstplugin/-/releases +// * IEM Plug-in Suite: https://plugins.iem.at/download/ +// * IEM OSC Plug-in: https://git.iem.at/ressi/iempluginosc + +// To run this sonification, click this line and press CTRL + ENTER on the keyboard +// When finished, press CTRL + . on you keyboard simultaneously to stop the sonification + +s.quit; +o = Server.default.options; +o.numOutputBusChannels = 2; +o.numOutputBusChannels; +o.memSize = 32*8192; + +// Set the surround setting +// 0: Stereo (Binaurual) +// 1: VisC Dome +// 2: Hayden +~setup = 0; + +if((~setup == 0), + {~numSpeakerChannels = 2;} +); + +if((~setup == 1), + {o.outDevice_("ASIO : Focusrite USB ASIO"); + ~numSpeakerChannels = 8; + } +); + +if((~setup == 2), + {o.outDevice_("ASIO : ASIO MADIface USB"); + ~numSpeakerChannels = 32; + } +); + +s.reboot; +s.waitForBoot{ + + var loadData = { + + var mul = 1, orbitscale= 0.0, gravityscale=2, tempscale=174, tempscale2=2, tempscale3=99; + + ~time = 1; + + //Mass (10^24 kg), C2-C5 + ~massMercury = 523.25*mul;//C5 + ~massVenus = 329.63*mul;//E4 + ~massEarth = 261.63*mul;//C4 + ~massMars = 392.00*mul;//G4 + + ~massJupiter = 65.406*mul; //C2 + ~massSaturn = 82.41*mul; //E2 + ~massUranus = 130.81*mul; //C3 + ~massNeptune = 110.00*mul; //A2 + + //Moons, not scaled + ~massMoon = 659.25; //E5 + + ~massPhobos = 783.99; //G5 + ~massDeimos = 1046.50; //C6 + + ~massIo = 659.25; //E5, similar to moon + ~massEuropa = 783.99; //G5 + ~massGanymede = 440.00; //A4, largest moon of Jupiter + ~massCallisto = 523.25; //C5, similar mass to mercury + + ~massMimas = 1046.50; //C6 + ~massEnceladus = 880.00; //A5 + ~massTethys = 783.99; //G5 + ~massDione = 659.25; //E5, + ~massRhea = 523.25; //C5, + ~massTitan = 440.00; //A4, largest of Saturn + ~massHyperion = 1318.51; //E6 + ~massIapetus = 587.33; //D5 + + ~massAriel = 880.00; //A5 + ~massMiranda = 1046.50; //C6 + ~massOberon = 659.25; //E5 + ~massTitania = 523.25; //C5 + ~massUmbriel = 783.99; //G5 + + ~massTriton = 440.00; //A4 + + //Diameter + ~diameterMercury = 4879; + ~diameterVenus = 12104; + ~diameterEarth = 12756; + ~diameterMars = 6792; + + ~diameterJupiter = 142984; + ~diameterSaturn = 120536; + ~diameterUranus = 51118; + ~diameterNeptune = 49528; + + //orbital period, Earth ratio, (1 day/second) + ~orbitMercury = (1/88)*orbitscale; + ~orbitVenus = (1/224.7)*orbitscale; + ~orbitEarth = (1/365.2)*orbitscale; + ~orbitMars = (1/687)*orbitscale; + + ~orbitJupiter = (1/4331)*orbitscale; + ~orbitSaturn = (1/10747)*orbitscale; + ~orbitUranus = (1/30589)*orbitscale; + ~orbitNeptune = (1/59800)*orbitscale; + + ~orbitMoon = 1/27.3; + + ~orbitPhobos = 1/0.31891; + ~orbitDeimos = 1/1.26244; + + ~orbitIo = 1/1.8; + ~orbitEuropa = 1/3.6; + ~orbitGanymede = 1/7.2; + ~orbitCallisto = 1/16.7; + + ~orbitMimas = 1/0.9424218; + ~orbitEnceladus = 1/1.370218; + ~orbitTethys = 1/1.887802; + ~orbitDione = 1/2.736915; + ~orbitRhea = 1/4.517500; + ~orbitTitan = 1/15.945421; + ~orbitHyperion = 1/21.276609; + ~orbitIapetus = 1/79.330183; + + ~orbitAriel = 1/2.520379; + ~orbitMiranda = 1/1.413479; + ~orbitOberon = 1/13.463234; + ~orbitTitania = 1/8.705867; + ~orbitUmbriel = 1/4.144176; + + ~orbitTriton = 1/5.876854; + + //Length of day, ratio earth (1/rotationRatio),(24hrs/sec) + ~invrotationMercury = 1/175.9; + ~invrotationVenus = 1/116.8; //-, retrograde rotation + ~invrotationEarth = 1; + ~invrotationMars = 1/1.03; + + ~invrotationJupiter = 1/0.414; + ~invrotationSaturn = 1/0.444; + ~invrotationUranus = 1/0.718; //-, retrograde rotation + ~invrotationNeptune = 1/0.671; + + //Gravity (g), relation to Earth + ~gravityMercury = 0.378/gravityscale; + ~gravityVenus = 0.907/gravityscale; + ~gravityEarth = 1/gravityscale; + ~gravityMars = 0.377/gravityscale; + + ~gravityJupiter = 2.36/gravityscale; + ~gravitySaturn = 0.916/gravityscale; + ~gravityUranus = 0.889/gravityscale; + ~gravityNeptune = 1.12/gravityscale; + + //Avg temperature + ~tempMercury = (167+tempscale)*tempscale2; + ~tempVenus = (464+tempscale)*tempscale2; + ~tempEarth = (15+tempscale)*tempscale2; + ~tempMars = (-65+tempscale)*tempscale2; + + //Lowest temperature + ~lowtempMercury = 100-tempscale3; + ~lowtempVenus = 735-tempscale3; + ~lowtempEarth = 185-tempscale3; + ~lowtempMars = 120-tempscale3; + + //Highest temperature + ~hightempMercury = 700-tempscale3; + ~hightempVenus = 735-tempscale3; + ~hightempEarth = 331-tempscale3; + ~hightempMars = 293-tempscale3; + + //Gas giants only have Average temperature + ~lowtempJupiter = ~hightempJupiter = 163-tempscale3; + ~lowtempSaturn = ~hightempSaturn = 133-tempscale3; + ~lowtempUranus = ~hightempUranus = 100-tempscale3; //78 + ~lowtempNeptune = ~hightempNeptune = 100-tempscale3; //73 + + }; + + + var loadSynthDefs = { + + var filePath = thisProcess.nowExecutingPath.dirname; + + ~order = 2; // set this to the ambisonics order you want + ~numChannels = ((~order + 1)**2).asInteger; + + // binaural decoder (~numChannels -> 2) - reads from 'bus' and sums into 'out' + SynthDef.new(\binauralDecoder, { | bus, out = 0 | + Out.ar(out, VSTPlugin.ar(In.ar(bus, ~numChannels), 2)); + }).add; + + SynthDef.new(\allraDecoder, { | bus, out = 0 | + Out.ar(out, VSTPlugin.ar(In.ar(bus, ~numChannels), ~numSpeakerChannels)); + }).add; + + + // stereo encoder (2 -> ~numChannels) - replaces stereo signal with ambisonics signal + SynthDef.new(\stereoEncoder, { | bus = 0 | + ReplaceOut.ar(bus, VSTPlugin.ar(In.ar(bus, 2), ~numChannels)); + }).add; + + // ambisonics insert FX Surround (replaces input with output) + SynthDef.new(\ambiFX, { | bus = 0, bypass | + ReplaceOut.ar(bus, VSTPlugin.ar(In.ar(bus, ~numChannels), ~numChannels, bypass)); + }).add; + + // helper Synth (throws audio from ambi bus to ambi master bus) + SynthDef.new(\ambiThrow, { | from, to | + Out.ar(to, In.ar(from, ~numChannels)); + }).add; + + // Set the lag time for the distance data + ~poslagTime = 0.1; + + SynthDef(\surroundmod, { + arg out=0,gate=0, amp=0.3, amp2=1.0, freq=200, rate=1, time=1, pan=0, type=0, isMagnetic=0; + var sig, sig2, globalAmp, env, resfreq, lfo; + + env = EnvGen.kr( + Env.adsr(5.0,0.0,1.0,5.0), + gate, + doneAction:0); + + sig = Select.ar(type,[ + LFSaw.ar(Vibrato.kr(freq/2,rate*time,0.004),0,0.4), + LFPulse.ar(Vibrato.kr(freq,rate*time,0.004),0,0.4)]); + + //Sweeping resonant low-pass filter for length of day + resfreq = SinOsc.kr(rate*time) * 200 + 400; + sig = RLPF.ar(sig, resfreq,0.5); + + //Phaser sweep if planet has a magnetic field + lfo = LinLin.ar(Vibrato.ar(0.4,0.04,1.0,0,0,0.2,0.2), 0, 1, 600, 5000); + sig = Select.ar(isMagnetic, + [sig, sig + HPF.ar(BPF.ar(sig, lfo, 0.1)*2,freq*3)]); + + globalAmp = Lag.kr(amp2, ~poslagTime); + sig = sig * env * amp * globalAmp; + + Out.ar(out, sig); + }).add; + + SynthDef.new(\gravity, { + arg out=0,gate=0, amp=0.65, amp2=1.0, freq=200, rate=1, pan=0, gravity=1, type=0, time=1; + var sig, globalAmp, env, b, sf, gFreq; + + env = EnvGen.kr( + Env.adsr(5.0,0.0,1.0,5.0), + gate, + doneAction:0); + + gFreq = Select.kr(type,[ + freq;, + freq;]); + + //Physical model of a ball + sf = LFPulse.ar(rate*time,0.0); + b = TBall.ar(sf, gravity,0.03,0.01); + sig = Ringz.ar(b * 20, gFreq, 1.0); + + globalAmp = Lag.kr(amp2, ~poslagTime); + sig = sig * env * amp * globalAmp; + + Out.ar(out, sig); + }).add; + + SynthDef.new(\wind, { + arg out=0,gate=0, amp=0.4, amp2=1.0, rate=0.45, pan=0, type=0, gust=1, atmos=60; + var sig, globalAmp, env, lfo; + + env = EnvGen.kr( + Env.adsr(5.0,0.0,1.0,5.0), + gate, + doneAction:0); + + //Select signal depending on planet type + sig = Select.ar(type,[ + PinkNoise.ar(amp);, + BrownNoise.ar(amp);]); + + //Sweeping low-pass filter on noise to create wind sound + sig = LPF.ar(sig, Vibrato.kr(1000*gust,rate,rate,rateVariation:0.7,depthVariation:0.3)); + sig = LPF.ar(sig, Vibrato.kr(5000,rate,rate,rateVariation:0.7,depthVariation:0.3).lag(0.5)); + + //High-pass filter for thinner atmosphere + sig = HPF.ar(sig, atmos); + + globalAmp = Lag.kr(amp2, ~poslagTime); + sig = sig * env * amp * globalAmp; + + Out.ar(out, sig); + }).add; + + SynthDef.new(\fry, { + arg out=0,gate=0, amp=0.8, amp2=1.0, freq=440, rate=1, time=1, pan=0, type=0, lowtemp=20, hightemp=200; + var sig, globalAmp, env, newrate, newrate2, newrate3, grate; + + env = EnvGen.kr( + Env.adsr(5.0,0.0,1.0,5.0), + gate, + doneAction:0); + + //Set temperature range and length of day. + newrate = SinOsc.kr(rate*time).range(lowtemp,hightemp); + + newrate2 = SinOsc.kr(rate*time).range(lowtemp/2000,hightemp/2000); + + newrate3 = SinOsc.kr(rate*time).range((lowtemp*10)+20,(hightemp*10)+20); + + //Grating sound + sig = Dust.ar(newrate, 0.20); + + //Select Low-pass filter (depending on day/night) + //depending on if the temperature is dynamic or not + sig = Select.ar(type,[ + LPF.ar(sig,SinOsc.kr(rate*time).range(4000,13000));, + LPF.ar(sig,12000);]); + + sig = sig + BPF.ar(Crackle.ar(2.0),newrate3,3,newrate2); + + globalAmp = Lag.kr(amp2, ~poslagTime); + sig = sig * env * amp * globalAmp; + + Out.ar(out, sig); + }).add; + + SynthDef(\rings, { + arg out=0, gate=0, amp=0.2, amp2=1.0, freq=400, rate=1, pan=0, type=0, dev=1.04; + var sig, globalAmp, temp, env; + + env = EnvGen.kr( + Env.adsr(5.0,0.0,1.0,5.0), + gate, + doneAction:0); + + sig = 0; + 3.do{ + arg count; + temp = SinOsc.ar( + freq * + (count + 1) * + LFNoise1.kr({Rand(0.05,0.2)}!3).range(dev.reciprocal,dev) + ); + temp = temp * LFNoise1.kr({Rand(0.5,8)}!7).exprange(0.01,1); + sig = sig + temp; + }; + sig = LPF.ar(sig,400); + sig = sig * 0.5; + + globalAmp = Lag.kr(amp2, ~poslagTime); + sig = sig * env * amp * globalAmp; + + Out.ar(out, sig); + }).add; + + SynthDef(\percSolar, { + arg freq=400, rate=1, pan=0, out=0, amp=0.2, amp2=1.0, gate=0, phase=0, time=1; + var sig, globalAmp, env, t_gate=0; + + t_gate = gate * LFPulse.kr(rate*time,phase); + env = EnvGen.kr( + Env.perc(0.01,1/(rate*time)), + t_gate, + doneAction:0); + + sig = BrownNoise.ar(1); + sig = (BPF.ar(sig, freq*2, 0.004) * 50); + + globalAmp = Lag.kr(amp2, ~poslagTime); + sig = sig * env * amp * globalAmp; + Out.ar(out, sig); + }).add; + + SynthDef(\percMoon, { + arg out=0,freq=400, rate=1, pan=0, amp=0.3, ampMoon=1.0, gate=0, phase=0, time=1, pangate=0; + var sig, globalAmp, env, t_gate=0; + + t_gate = gate * LFPulse.kr(rate*time,phase); + + env = EnvGen.kr( + Env.perc(0.01,1/(rate*time)), + t_gate, + doneAction:0); + + sig = BrownNoise.ar(1); + sig = (BPF.ar(sig, freq, 0.005) * 20); + + globalAmp = Lag.kr(ampMoon, ~poslagTime); + sig = sig * env * amp * globalAmp; + Out.ar(out, sig); + }).add; + + + SynthDef(\sinamppoof, { + arg freq=400, rate=1, pan=0, out=0, amp=0.6, amp2=1.0, gate=0, time=1; + var sig, globalAmp, sig2, env, env2, t_gate=0,oscillator1, oscillator2, resfreq, sinlvl; + + env = EnvGen.kr( + Env.adsr(0.01,0.0,0.3,0.1), + gate, + doneAction:0); + env2 = EnvGen.kr( + Env.adsr(0.05,0.5,0.3,0.5), + gate, + doneAction:0); + + sinlvl = SinOsc.kr(rate*time).range(0,1); + + sig = BrownNoise.ar(1); + sig2 = (BPF.ar(sig, freq*1, 0.01) * 5) * (1-sinlvl); + sig = (BPF.ar(sig, freq*2, 0.005) * 20)* sinlvl; + + globalAmp = Lag.kr(amp2, ~poslagTime); + sig = sig * env; + sig2 = sig2 * env2; + sig = (sig + sig2)/2 * amp * globalAmp; + Out.ar(out, sig); + }).add; + }; + + // create ambisonic master section + var loadAmbiGroups = { + + // bus + group + ~ambiMasterBus = Bus.audio(s, ~numChannels); + ~ambiMasterGroup = Group.new; + + if((~setup == 0), + // binaural decoder (writes to master output) + {~decoder = VSTPluginController(Synth(\binauralDecoder, [\bus, ~ambiMasterBus, \out, 0], target: ~ambiMasterGroup, addAction: \addToTail)).open("BinauralDecoder");}, + // AllRA decoder + {~decoder = VSTPluginController(Synth(\allraDecoder, [\bus, ~ambiMasterBus, \out, 0], target: ~ambiMasterGroup, addAction: \addToTail)).open("SimpleDecoder");} + ); + + // a group for ambisonic master effects + ~ambiMasterFXGroup = Group.before(~decoder.synth); + + //Groups + ~solarGrp = Group.new; + ~innerSolarGrp = Group.new(~solarGrp); + ~outerSolarGrp = Group.new(~solarGrp); + + ~planetaryGrp = Group.new; + ~innerPlanetaryGrp = Group.new(~planetaryGrp); + ~outerPlanetaryGrp = Group.new(~planetaryGrp); + + ~mercuryGrp = Group.new(~innerPlanetaryGrp); + ~venusGrp = Group.new(~innerPlanetaryGrp); + ~earthGrp = Group.new(~innerPlanetaryGrp); + ~marsGrp = Group.new(~innerPlanetaryGrp); + ~jupiterGrp = Group.new(~outerPlanetaryGrp); + ~saturnGrp = Group.new(~outerPlanetaryGrp); + ~uranusGrp = Group.new(~outerPlanetaryGrp); + ~neptuneGrp = Group.new(~outerPlanetaryGrp); + + //~fxGrp = Group.after(~solarGrp); + ~solarGrp = Group.before(~ambiMasterGroup); + + }; + + var initiateSynths = { + + ~moonMode = \percMoon; + + //Mercury + ~ambiBusMercury = Bus.audio(s, ~numChannels); + + ~mercuryP = Synth.new(\surroundmod, [ + \amp, 0.2, + \type, 0, + \freq, ~massMercury, + \rate, ~invrotationMercury, + \isMagnetic, 1, + \out, ~ambiBusMercury], ~mercuryGrp, addAction: \addToHead); + + ~mercuryG = Synth.new(\gravity, [ + \amp, 0.5, + \type, 0, + \freq, ~massMercury, + \rate, ~gravityMercury/2, + \gravity, ~gravityMercury, + \out, ~ambiBusMercury], ~mercuryGrp, addAction: \addToHead); + + ~mercuryT = Synth.new(\fry, [ + \rate, ~invrotationMercury, + \type, 0, + \lowtemp, ~lowtempMercury, + \hightemp, ~hightempMercury, + \out, ~ambiBusMercury], ~mercuryGrp, addAction: \addToHead); + + ~encoderMercury = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBusEarth], target: ~mercuryGrp, addAction: \addToTail)).open("StereoEncoder"); + Synth(\ambiThrow, [\from, ~ambiBusMercury, \to, ~ambiMasterBus], target: ~mercuryGrp, addAction: \addToTail); + + //Venus + ~ambiBusVenus = Bus.audio(s, ~numChannels); + + ~venusP = Synth.new(\surroundmod, [ + \amp, 0.2, + \type, 0, + \freq, ~massVenus, + \rate, ~invrotationVenus, + \isMagnetic, 0, + \out, ~ambiBusVenus], ~venusGrp, addAction: \addToHead); + + ~venusG = Synth.new(\gravity, [ + \type, 0, + \amp, 0.8, + \freq, ~massVenus, + \rate, ~gravityVenus/4, + \gravity, ~gravityVenus, + \out, ~ambiBusVenus], ~venusGrp, addAction: \addToHead); + + ~venusW = Synth.new(\wind, [ + \amp, 0.5, + \type, 1, + \rate, 0.6, + \gust, 2, + \out, ~ambiBusVenus], ~venusGrp, addAction: \addToHead); + + ~venusT = Synth.new(\fry, [ + \type, 1, + \rate, ~invrotationVenus, + \lowtemp, ~lowtempVenus , + \hightemp, ~hightempVenus, + \out, ~ambiBusVenus], ~venusGrp, addAction: \addToHead); + + ~encoderVenus = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBusVenus], target: ~venusGrp, addAction: \addToTail)).open("StereoEncoder"); + Synth(\ambiThrow, [\from, ~ambiBusVenus, \to, ~ambiMasterBus], target: ~venusGrp, addAction: \addToTail); + + + //Earth + ~ambiBusEarth = Bus.audio(s, ~numChannels); + + ~earthP = Synth.new(\surroundmod, [ + \type, 0, + \freq, ~massEarth, + \rate, ~invrotationEarth, + \isMagnetic, 1, + \out, ~ambiBusEarth], ~earthGrp, addAction: \addToHead); + + ~earthG = Synth.new(\gravity, [ + \type, 0, + \freq, ~massEarth, + \rate, ~invrotationEarth/4, + \gravity, ~gravityEarth, + \out, ~ambiBusEarth], ~earthGrp, addAction: \addToHead); + + ~earthW = Synth.new(\wind, [ + \amp, 0.7, + \type, 0, + \rate, 0.3, + \gust, 1, + \out, ~ambiBusEarth], ~earthGrp, addAction: \addToHead); + + ~earthT = Synth.new(\fry, [ + \type, 0, + \rate, ~invrotationEarth, + \lowtemp, ~lowtempEarth , + \hightemp, ~hightempEarth, + \out, ~ambiBusEarth], ~earthGrp, addAction: \addToHead); + + ~encoderEarth = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBusEarth], target: ~earthGrp, addAction: \addToTail)).open("StereoEncoder"); + Synth(\ambiThrow, [\from, ~ambiBusEarth, \to, ~ambiMasterBus], target: ~earthGrp, addAction: \addToTail); + + //Moon + ~ambiBusMoon = Bus.audio(s, ~numChannels); + + ~moonP = Synth.new(~moonMode, [ + \freq, ~massMoon, + \rate, ~orbitMoon, + \out, ~ambiBusMoon], ~earthGrp, addAction: \addToHead); + + ~encoderMoon = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBusMoon], target: ~earthGrp, addAction: \addToTail)).open("StereoEncoder"); + Synth(\ambiThrow, [\from, ~ambiBusMoon, \to, ~ambiMasterBus], target: ~earthGrp, addAction: \addToTail); + + //Mars + ~ambiBusMars = Bus.audio(s, ~numChannels); + + ~marsP = Synth.new(\surroundmod, [ + \type, 0, + \freq, ~massMars, + \rate, ~invrotationMars, + \isMagnetic, 0, + \out, ~ambiBusMars], ~marsGrp, addAction: \addToHead); + + ~marsG = Synth.new(\gravity, [ + \type, 0, + \freq, ~massMars, + \rate, ~invrotationMars/5, + \gravity, ~gravityMars, + \out, ~ambiBusMars], ~marsGrp, addAction: \addToHead); + + ~marsW = Synth.new(\wind, [ + \amp, 0.6, + \type, 0, + \rate, 0.1, + \gust, 2, + \atmos, 400, + \out, ~ambiBusMars], ~marsGrp, addAction: \addToHead); + + ~marsT = Synth.new(\fry, [ + \type, 0, + \rate, ~invrotationMars, + \lowtemp, ~lowtempMars, + \hightemp, ~hightempMars, + \out, ~ambiBusMars], ~marsGrp, addAction: \addToHead); + + ~encoderMars = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBusMars], target: ~marsGrp, addAction: \addToTail)).open("StereoEncoder"); + Synth(\ambiThrow, [\from, ~ambiBusMars, \to, ~ambiMasterBus], target: ~marsGrp, addAction: \addToTail); + + //Phobos + ~ambiBusPhobos = Bus.audio(s, ~numChannels); + + ~phobosP = Synth.new(~moonMode, [ + \freq, ~massPhobos, + \rate, ~orbitPhobos, + \out, ~ambiBusPhobos], ~marsGrp, addAction: \addToHead); + + ~encoderPhobos = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBusPhobos], target: ~marsGrp, addAction: \addToTail)).open("StereoEncoder"); + Synth(\ambiThrow, [\from, ~ambiBusPhobos, \to, ~ambiMasterBus], target: ~marsGrp, addAction: \addToTail); + + //Deimos + ~ambiBusDeimos = Bus.audio(s, ~numChannels); + + ~deimosP = Synth.new(~moonMode, [ + \freq, ~massDeimos, + \rate, ~orbitDeimos, + \out, ~ambiBusDeimos], ~marsGrp, addAction: \addToHead); + + ~encoderDeimos = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBusDeimos], target: ~marsGrp, addAction: \addToTail)).open("StereoEncoder"); + Synth(\ambiThrow, [\from, ~ambiBusDeimos, \to, ~ambiMasterBus], target: ~marsGrp, addAction: \addToTail); + + + //Jupiter + ~ambiBusJupiter = Bus.audio(s, ~numChannels); + + ~jupiterP = Synth.new(\surroundmod, [ + \amp, 0.5, + \type, 1, + \freq, ~massJupiter, + \rate, ~invrotationJupiter, + \isMagnetic, 1, + \out, ~ambiBusJupiter], ~jupiterGrp, addAction: \addToHead); + + ~jupiterG = Synth.new(\gravity, [ + \amp, 0.8, + \type, 1, + \freq, ~massJupiter, + \rate, ~invrotationJupiter/4, + \gravity, ~gravityJupiter, + \out, ~ambiBusJupiter], ~jupiterGrp, addAction: \addToHead); + + ~jupiterW = Synth.new(\wind, [ + \amp, 0.5, + \type, 1, + \rate, 0.5, + \gust, 0.5, + \out, ~ambiBusJupiter], ~jupiterGrp, addAction: \addToHead); + + ~jupiterT = Synth.new(\fry, [ + \type, 1, + \rate, ~invrotationJupiter, + \lowtemp, ~lowtempJupiter, + \hightemp, ~hightempJupiter, + \out, ~ambiBusJupiter], ~jupiterGrp, addAction: \addToHead); + + ~encoderJupiter = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBusJupiter], target: ~jupiterGrp, addAction: \addToTail)).open("StereoEncoder"); + Synth(\ambiThrow, [\from, ~ambiBusJupiter, \to, ~ambiMasterBus], target: ~jupiterGrp, addAction: \addToTail); + + //Io + ~ambiBusIo = Bus.audio(s, ~numChannels); + + ~ioP = Synth.new(~moonMode, [ + \freq, ~massIo, + \rate, ~orbitIo, + \out, ~ambiBusIo], ~jupiterGrp, addAction: \addToHead); + + ~encoderIo = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBusIo], target: ~jupiterGrp, addAction: \addToTail)).open("StereoEncoder"); + Synth(\ambiThrow, [\from, ~ambiBusIo, \to, ~ambiMasterBus], target: ~jupiterGrp, addAction: \addToTail); + + //Europa + ~ambiBusEuropa = Bus.audio(s, ~numChannels); + + ~europaP = Synth.new(~moonMode, [ + \freq, ~massEuropa, + \rate, ~orbitEuropa, + \out, ~ambiBusEuropa], ~jupiterGrp, addAction: \addToHead); + + ~encoderEuropa = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBusEuropa], target: ~jupiterGrp, addAction: \addToTail)).open("StereoEncoder"); + Synth(\ambiThrow, [\from, ~ambiBusEuropa, \to, ~ambiMasterBus], target: ~jupiterGrp, addAction: \addToTail); + + //Ganymede + ~ambiBusGanymede = Bus.audio(s, ~numChannels); + + ~ganymedeP = Synth.new(~moonMode, [ + \freq, ~massGanymede, + \rate, ~orbitGanymede, + \out, ~ambiBusGanymede], ~jupiterGrp, addAction: \addToHead); + + ~encoderGanymede = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBusGanymede], target: ~jupiterGrp, addAction: \addToTail)).open("StereoEncoder"); + Synth(\ambiThrow, [\from, ~ambiBusGanymede, \to, ~ambiMasterBus], target: ~jupiterGrp, addAction: \addToTail); + + //Callisto + ~ambiBusCallisto = Bus.audio(s, ~numChannels); + + ~callistoP = Synth.new(~moonMode, [ + \freq, ~massCallisto, + \rate, ~orbitCallisto, + \out, ~ambiBusCallisto], ~jupiterGrp, addAction: \addToHead); + + ~encoderCallisto = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBusCallisto], target: ~jupiterGrp, addAction: \addToTail)).open("StereoEncoder"); + Synth(\ambiThrow, [\from, ~ambiBusCallisto, \to, ~ambiMasterBus], target: ~jupiterGrp, addAction: \addToTail); + + //Saturn + ~ambiBusSaturn = Bus.audio(s, ~numChannels); + + + ~saturnP = Synth.new(\surroundmod, [ + \amp, 0.4, + \type, 1, + \freq, ~massSaturn, + \rate, ~invrotationSaturn, + \isMagnetic, 1, + \out, ~ambiBusSaturn], ~saturnGrp, addAction: \addToHead); + + ~saturnG = Synth.new(\gravity, [ + \type, 1, + \freq, ~massSaturn, + \rate, ~invrotationSaturn/4, + \gravity, ~gravitySaturn, + \out, ~ambiBusSaturn], ~saturnGrp, addAction: \addToHead); + + ~saturnW = Synth.new(\wind, [ + \amp, 0.5, + \type, 1, + \rate, 0.6, + \gust, 1.0, + \out, ~ambiBusSaturn], ~saturnGrp, addAction: \addToHead); + + ~saturnT = Synth.new(\fry, [ + \type, 1, + \rate, ~invrotationSaturn, + \lowtemp, ~lowtempSaturn, + \hightemp, ~hightempSaturn, + \out, ~ambiBusSaturn], ~saturnGrp, addAction: \addToHead); + + ~saturnR = Synth.new(\rings, [ + \freq, ~massSaturn*4, + \rate, ~invrotationSaturn, + \out, ~ambiBusSaturn], ~saturnGrp, addAction: \addToHead); + + ~encoderSaturn = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBusSaturn], target: ~saturnGrp, addAction: \addToTail)).open("StereoEncoder"); + Synth(\ambiThrow, [\from, ~ambiBusSaturn, \to, ~ambiMasterBus], target: ~saturnGrp, addAction: \addToTail); + + //Mimas + ~ambiBusMimas = Bus.audio(s, ~numChannels); + + ~mimasP = Synth.new(~moonMode, [ + \freq, ~massMimas, + \rate, ~orbitMimas, + \out, ~ambiBusMimas], ~saturnGrp, addAction: \addToHead); + + ~encoderMimas = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBusMimas], target: ~saturnGrp, addAction: \addToTail)).open("StereoEncoder"); + Synth(\ambiThrow, [\from, ~ambiBusMimas, \to, ~ambiMasterBus], target: ~saturnGrp, addAction: \addToTail); + + //Enceladus + ~ambiBusEnceladus = Bus.audio(s, ~numChannels); + + ~enceladusP = Synth.new(~moonMode, [ + \freq, ~massEnceladus, + \rate, ~orbitEnceladus, + \out, ~ambiBusEnceladus], ~saturnGrp, addAction: \addToHead); + + ~encoderEnceladus = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBusEnceladus], target: ~saturnGrp, addAction: \addToTail)).open("StereoEncoder"); + Synth(\ambiThrow, [\from, ~ambiBusEnceladus, \to, ~ambiMasterBus], target: ~saturnGrp, addAction: \addToTail); + + //Tethys + ~ambiBusTethys = Bus.audio(s, ~numChannels); + + ~tethysP = Synth.new(~moonMode, [ + \freq, ~massTethys, + \rate, ~invrotationSaturn/8, + \phase, 0.375, + \out, ~ambiBusTethys], ~saturnGrp, addAction: \addToHead); + + ~encoderTethys = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBusTethys], target: ~saturnGrp, addAction: \addToTail)).open("StereoEncoder"); + Synth(\ambiThrow, [\from, ~ambiBusTethys, \to, ~ambiMasterBus], target: ~saturnGrp, addAction: \addToTail); + + //Dione + ~ambiBusDione = Bus.audio(s, ~numChannels); + + ~dioneP = Synth.new(~moonMode, [ + \freq, ~massDione, + \rate, ~orbitDione, + \out, ~ambiBusDione], ~saturnGrp, addAction: \addToHead); + + ~encoderDione = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBusDione], target: ~saturnGrp, addAction: \addToTail)).open("StereoEncoder"); + Synth(\ambiThrow, [\from, ~ambiBusDione, \to, ~ambiMasterBus], target: ~saturnGrp, addAction: \addToTail); + + //Rhea + ~ambiBusRhea = Bus.audio(s, ~numChannels); + + ~rheaP = Synth.new(~moonMode, [ + \freq, ~massRhea, + \rate, ~orbitRhea, + \out, ~ambiBusRhea], ~saturnGrp, addAction: \addToHead); + + ~encoderRhea = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBusRhea], target: ~saturnGrp, addAction: \addToTail)).open("StereoEncoder"); + Synth(\ambiThrow, [\from, ~ambiBusRhea, \to, ~ambiMasterBus], target: ~saturnGrp, addAction: \addToTail); + + //Titan + ~ambiBusTitan = Bus.audio(s, ~numChannels); + + ~titanP = Synth.new(~moonMode, [ + \freq, ~massTitan, + \rate, ~orbitTitan, + \out, ~ambiBusTitan], ~saturnGrp, addAction: \addToHead); + + ~encoderTitan = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBusTitan], target: ~saturnGrp, addAction: \addToTail)).open("StereoEncoder"); + Synth(\ambiThrow, [\from, ~ambiBusTitan, \to, ~ambiMasterBus], target: ~saturnGrp, addAction: \addToTail); + + //Hyperion + ~ambiBusHyperion = Bus.audio(s, ~numChannels); + + ~hyperionP = Synth.new(~moonMode, [ + \freq, ~massHyperion, + \rate, ~orbitHyperion, + \out, ~ambiBusHyperion], ~saturnGrp, addAction: \addToHead); + + ~encoderHyperion = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBusHyperion], target: ~saturnGrp, addAction: \addToTail)).open("StereoEncoder"); + Synth(\ambiThrow, [\from, ~ambiBusHyperion, \to, ~ambiMasterBus], target: ~saturnGrp, addAction: \addToTail); + + //Iapetus + ~ambiBusIapetus = Bus.audio(s, ~numChannels); + + ~iapetusP = Synth.new(~moonMode, [ + \freq, ~massIapetus, + \rate, ~orbitIapetus, + \out, ~ambiBusIapetus], ~saturnGrp, addAction: \addToHead); + + ~encoderIapetus = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBusIapetus], target: ~saturnGrp, addAction: \addToTail)).open("StereoEncoder"); + Synth(\ambiThrow, [\from, ~ambiBusIapetus, \to, ~ambiMasterBus], target: ~saturnGrp, addAction: \addToTail); + + + //Uranus + ~ambiBusUranus = Bus.audio(s, ~numChannels); + + ~uranusP = Synth.new(\surroundmod, [ + \amp, 0.4, + \type, 1, + \freq, ~massUranus, + \rate, ~invrotationUranus, + \isMagnetic, 1, + \out, ~ambiBusUranus], ~uranusGrp, addAction: \addToHead); + + ~uranusG = Synth.new(\gravity, [ + \type, 1, + \freq, ~massUranus, + \rate, ~invrotationUranus/4, + \gravity, ~gravityUranus, + \out, ~ambiBusUranus], ~uranusGrp, addAction: \addToHead); + + ~uranusW = Synth.new(\wind, [ + \amp, 0.5, + \type, 1, + \rate, 0.5, + \gust, 0.7, + \out, ~ambiBusUranus], ~uranusGrp, addAction: \addToHead); + ~uranusT = Synth.new(\fry, [ + \type, 1, + \rate, ~invrotationUranus, + \lowtemp, ~lowtempUranus, + \hightemp, ~hightempUranus, + \out, ~ambiBusUranus], ~uranusGrp, addAction: \addToHead); + + ~encoderUranus = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBusUranus], target: ~uranusGrp, addAction: \addToTail)).open("StereoEncoder"); + Synth(\ambiThrow, [\from, ~ambiBusUranus, \to, ~ambiMasterBus], target: ~uranusGrp, addAction: \addToTail); + + //Ariel + ~ambiBusAriel = Bus.audio(s, ~numChannels); + + ~arielP = Synth.new(~moonMode, [ + \freq, ~massAriel, + \rate, ~orbitAriel, + \out, ~ambiBusAriel], ~uranusGrp, addAction: \addToHead); + + ~encoderAriel = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBusAriel], target: ~uranusGrp, addAction: \addToTail)).open("StereoEncoder"); + Synth(\ambiThrow, [\from, ~ambiBusAriel, \to, ~ambiMasterBus], target: ~uranusGrp, addAction: \addToTail); + + //Miranda + ~ambiBusMiranda = Bus.audio(s, ~numChannels); + + ~mirandaP = Synth.new(~moonMode, [ + \freq, ~massMiranda, + \rate, ~orbitMiranda, + \out, ~ambiBusMiranda], ~uranusGrp, addAction: \addToHead); + + ~encoderMiranda = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBusMiranda], target: ~uranusGrp, addAction: \addToTail)).open("StereoEncoder"); + Synth(\ambiThrow, [\from, ~ambiBusMiranda, \to, ~ambiMasterBus], target: ~uranusGrp, addAction: \addToTail); + + //Oberon + ~ambiBusOberon = Bus.audio(s, ~numChannels); + + ~oberonP = Synth.new(~moonMode, [ + \freq, ~massOberon, + \rate, ~orbitOberon, + \out, ~ambiBusOberon], ~uranusGrp, addAction: \addToHead); + + ~encoderOberon = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBusOberon], target: ~uranusGrp, addAction: \addToTail)).open("StereoEncoder"); + Synth(\ambiThrow, [\from, ~ambiBusOberon, \to, ~ambiMasterBus], target: ~uranusGrp, addAction: \addToTail); + + //Titania + ~ambiBusTitania = Bus.audio(s, ~numChannels); + + ~titaniaP = Synth.new(~moonMode, [ + \freq, ~massTitania, + \rate, ~orbitTitania, + \out, ~ambiBusTitania], ~uranusGrp, addAction: \addToHead); + + ~encoderTitania = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBusTitania], target: ~uranusGrp, addAction: \addToTail)).open("StereoEncoder"); + Synth(\ambiThrow, [\from, ~ambiBusTitania, \to, ~ambiMasterBus], target: ~uranusGrp, addAction: \addToTail); + + //Umbriel + ~ambiBusUmbriel = Bus.audio(s, ~numChannels); + + ~umbrielP = Synth.new(~moonMode, [ + \freq, ~massUmbriel, + \rate, ~orbitUmbriel, + \out, ~ambiBusUmbriel], ~uranusGrp, addAction: \addToHead); + + ~encoderUmbriel = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBusUmbriel], target: ~uranusGrp, addAction: \addToTail)).open("StereoEncoder"); + Synth(\ambiThrow, [\from, ~ambiBusUmbriel, \to, ~ambiMasterBus], target: ~uranusGrp, addAction: \addToTail); + + //Neptune + ~ambiBusNeptune = Bus.audio(s, ~numChannels); + + ~neptuneP = Synth.new(\surroundmod, [ + \amp, 0.4, + \type, 1, + \freq, ~massNeptune, + \rate, ~invrotationNeptune, + \isMagnetic, 1, + \out, ~ambiBusNeptune], ~neptuneGrp, addAction: \addToHead); + + ~neptuneG = Synth.new(\gravity, [ + \type, 1, + \freq, ~massNeptune, + \rate, ~invrotationNeptune/4, + \gravity, ~gravityNeptune, + \out, ~ambiBusNeptune], ~neptuneGrp, addAction: \addToHead); + + ~neptuneW = Synth.new(\wind, [ + \amp, 0.5, + \type, 1, + \rate, 0.6, + \gust, 2, + \out, ~ambiBusNeptune], ~neptuneGrp, addAction: \addToHead); + + ~neptuneT = Synth.new(\fry, [ + \rate, ~invrotationNeptune, + \lowtemp, ~lowtempNeptune, + \hightemp, ~hightempNeptune, + \out, ~ambiBusNeptune], ~neptuneGrp, addAction: \addToHead); + + ~encoderNeptune = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBusNeptune], target: ~neptuneGrp, addAction: \addToTail)).open("StereoEncoder"); + Synth(\ambiThrow, [\from, ~ambiBusNeptune, \to, ~ambiMasterBus], target: ~neptuneGrp, addAction: \addToTail); + + //Triton + ~ambiBusTriton = Bus.audio(s, ~numChannels); + + ~tritonP = Synth.new(~moonMode, [ + \freq, ~massTriton, + \rate, ~orbitTriton, + \out, ~ambiBusTriton], ~neptuneGrp, addAction: \addToHead); + + ~encoderTriton = VSTPluginController(Synth(\stereoEncoder, [\bus, ~ambiBusTriton], target: ~neptuneGrp, addAction: \addToTail)).open("StereoEncoder"); + Synth(\ambiThrow, [\from, ~ambiBusTriton, \to, ~ambiMasterBus], target: ~neptuneGrp, addAction: \addToTail); + + + //SOLAR SYSTEM VIEW + + ~solarMode = \percSolar; + //~solarMode = \sinamppoof; + + //Mercury Solar + ~mercuryPoof = Synth.new(\sinamppoof, [ + \freq, ~massMercury, + \rate, ~invrotationMercury, + \out, ~ambiBusMercury], ~mercuryGrp, addAction: \addToHead); + + //Venus Solar + ~venusPoof = Synth.new(\sinamppoof, [ + \freq, ~massVenus, + \rate, ~invrotationVenus, + \out, ~ambiBusVenus], ~venusGrp, addAction: \addToHead); + + //Earth Solar + ~earthPoof = Synth.new(~solarMode, [ + \freq, ~massEarth, + \rate, ~invrotationEarth, + \out, ~ambiBusEarth], ~earthGrp, addAction: \addToHead); + + //Mars Solar + ~marsPoof = Synth.new(~solarMode, [ + \freq, ~massMars, + \rate, ~invrotationMars, + \out, ~ambiBusMars], ~marsGrp, addAction: \addToHead); + + //Jupiter Solar + ~jupiterPoof = Synth.new(~solarMode, [ + \freq, ~massJupiter, + \rate, ~invrotationJupiter, + \out, ~ambiBusJupiter], ~jupiterGrp, addAction: \addToHead); + + //Saturn Solar + ~saturnPoof = Synth.new(~solarMode, [ + \freq, ~massSaturn, + \rate, ~invrotationSaturn, + \out, ~ambiBusSaturn], ~saturnGrp, addAction: \addToHead); + + //Uranus Solar + ~uranusPoof = Synth.new(~solarMode, [ + \freq, ~massUranus, + \rate, ~invrotationUranus, + \out, ~ambiBusUranus], ~uranusGrp, addAction: \addToHead); + + //Neptune Solar + ~neptunePoof = Synth.new(~solarMode, [ + \freq, ~massNeptune, + \rate, ~invrotationNeptune, + \out, ~ambiBusNeptune], ~neptuneGrp, addAction: \addToHead); + + }; + + var loadDecoder = { + + if((~setup == 1), + { + ~decoder.iemPluginOSC("/SimpleDecoder/loadFile", thisProcess.nowExecutingPath.dirname +/+ "AmbiDecoders" +/+ "DomenVisC_5th.json"); + 0.1.wait; + ~decoder.iemPluginOSC("/SimpleDecoder/swMode", 1); + 0.1.wait; + ~decoder.iemPluginOSC("/SimpleDecoder/swChannel", 4); + 0.1.wait; + ~decoder.iemPluginOSC("/SimpleDecoder/lowPassGain", -12); + } + ); + + if((~setup == 2), + { + ~decoder.iemPluginOSC("/SimpleDecoder/loadFile", thisProcess.nowExecutingPath.dirname +/+ "AmbiDecoders" +/+ "HaydenIEM_5th_0deg_80top_rot180deg.json"); + 0.1.wait; + ~decoder.iemPluginOSC("/SimpleDecoder/swMode", 1); + 0.1.wait; + ~decoder.iemPluginOSC("/SimpleDecoder/swChannel", 32); + 0.1.wait; + } + ); + + }; + + var loadOSC = { + + ~compareGate = 0; + ~minDist = 3; + + //Horizontal mode + ~modeElSign = 1; + ~modeElPhase = 0.5; + + //Circular mode (change manually) + // ~modeElSign = -1; + //~modeElPhase = 0.75; + + OSCdef.new(\Mode, + { + arg msg; + + //msg[1] == 0 -> Horizontal + //msg[1] == 1 -> Circular + + //msg[2] == 0 -> Elevation on + //msg[2] == 1 -> Elevation off + + ("SurroundMode:" + msg[1]).postln; + + //Horizontal + if(((msg[1]==0)), + {~modeElSign = 1; + ~modeElPhase = 0.5;}, + {} + ); + + //Circular + if(((msg[1]==1)), + {~modeElSign = -1; + ~modeElPhase = 0.75;}, + {} + ); + + ("~modeElSign:" + ~modeElSign).postln; + ("~modeElPhase:" + ~modeElPhase).postln; + + },'/Mode'); + + OSCdef.new(\Time, + { + arg msg; + + //("time:" + msg[1]).postln; + + ~planetaryGrp.set(\time, abs(msg[1])); + ~solarGrp.set(\time, abs(msg[1])); + + },'/Time'); + + + OSCdef.new(\mercury, + { + arg msg; + var amp = (-5.4e-7*1.1*msg[1]).exp*1.05; + + if(~compareGate == 0, + {if(msg[4][0]==1, + {~mercuryP.set(\gate, 1);}, + {~mercuryP.set(\gate, 0);}); + + if(msg[4][1]==1, + {~mercuryG.set(\gate, 1);}, + {~mercuryG.set(\gate, 0);}); + + if(msg[4][2]==1, + {~mercuryT.set(\gate, 1);}, + {~mercuryT.set(\gate, 0);}); + + if(msg[4][3]==1, + {~mercuryW.set(\gate, 1);}, + {~mercuryW.set(\gate, 0);}); + + if(amp>1.0, + {amp = 1.0}, + {amp = (-5.4e-7*1.1*msg[1]).exp*1.05}); + + ~mercuryGrp.set(\amp2, amp);}, + {~mercuryGrp.set(\amp2, 1.0);}); + + ~encoderMercury.do(_.set(6, (msg[2]/(2*pi))+0.5)); + ~encoderMercury.do(_.set(7, ~modeElSign*(msg[3]/(2*pi))+~modeElPhase)); + + },'/Mercury'); + + OSCdef.new(\venus, + { + arg msg; + var amp = (-5.4e-7*1.1*msg[1]).exp*1.05; + var azimuth, elevation; + + if(~compareGate == 0, + {if(msg[4][0]==1, + {~venusP.set(\gate, 1);}, + {~venusP.set(\gate, 0);}); + + if(msg[4][1]==1, + {~venusG.set(\gate, 1);}, + {~venusG.set(\gate, 0);}); + + if(msg[4][2]==1, + {~venusT.set(\gate, 1);}, + {~venusT.set(\gate, 0);}); + + if(msg[4][3]==1, + {~venusW.set(\gate, 1);}, + {~venusW.set(\gate, 0);}); + + if(amp>1.0, + {amp = 1.0}, + {amp = (-5.4e-7*1.1*msg[1]).exp*1.05}); + + ~venusGrp.set(\amp2, amp);}, + {~venusGrp.set(\amp2, 1.0);}); + + ~encoderVenus.do(_.set(6, (msg[2]/(2*pi))+0.5)); + ~encoderVenus.do(_.set(7, ~modeElSign*(msg[3]/(2*pi))+~modeElPhase)); + + },'/Venus'); + + OSCdef.new(\earth, + { + arg msg; + + var ampMoon; + var amp = (-5.4e-7*1.1*msg[1]).exp*1.05; + var azimuth, elevation; + + ("Earth:" + msg).postln; + + if(~compareGate == 0, + {if(msg[4][0]==1, + {~earthP.set(\gate, 1);}, + {~earthP.set(\gate, 0);}); + + if(msg[4][1]==1, + {~earthG.set(\gate, 1);}, + {~earthG.set(\gate, 0);}); + + if(msg[4][2]==1, + {~earthT.set(\gate, 1);}, + {~earthT.set(\gate, 0);}); + + if(msg[4][3]==1, + {~earthW.set(\gate, 1);}, + {~earthW.set(\gate, 0);}); + + if(msg[4][4]==1, + {~moonP.set(\gate, 1);}, + {~moonP.set(\gate, 0);}); + + if(amp>1.0, + {amp = 1.0}, + {amp = (-5.4e-7*1.1*msg[1]).exp*1.05}); + + ~earthGrp.set(\amp2, amp);}, + {~earthGrp.set(\amp2, 1.0);}); + + ampMoon = -4*(amp - 0.5).pow(2)+1; + ~earthGrp.set(\ampMoon, ampMoon); + + ~encoderEarth.do(_.set(6, (msg[2]/(2*pi))+0.5)); + ~encoderEarth.do(_.set(7, ~modeElSign*(msg[3]/(2*pi))+~modeElPhase)); + + ~encoderMoon.do(_.set(6, (msg[6]/(2*pi))+0.5)); + ~encoderMoon.do(_.set(7, ~modeElSign*(msg[7]/(2*pi))+~modeElPhase)); + + },'/Earth'); + + OSCdef.new(\mars, + { + arg msg; + var ampMoon; + var amp = (-9.5e-6*0.5*msg[1]).exp*1.1; + var azimuth, elevation; + + if(~compareGate == 0, + {if(msg[4][0]==1, + {~marsP.set(\gate, 1);}, + {~marsP.set(\gate, 0);}); + + if(msg[4][1]==1, + {~marsG.set(\gate, 1);}, + {~marsG.set(\gate, 0);}); + + if(msg[4][2]==1, + {~marsT.set(\gate, 1);}, + {~marsT.set(\gate, 0);}); + + if(msg[4][3]==1, + {~marsW.set(\gate, 1);}, + {~marsW.set(\gate, 0);}); + + if(msg[4][4]==1, + {~phobosP.set(\gate, 1); + ~deimosP.set(\gate, 1); + }, + {~phobosP.set(\gate, 0); + ~deimosP.set(\gate, 0);}); + + if(amp>1.0, + {amp = 1.0}, + {amp = (-9.5e-6*0.5*msg[1]).exp*1.1}); + + if(0>amp, + {amp = 0.0}, + {amp = (-9.5e-6*0.5*msg[1]).exp*1.1}); + + ~marsGrp.set(\amp2, amp);}, + {~marsGrp.set(\amp2, 1.0);}); + + ampMoon = -4*(amp - 0.5).pow(2)+1; + ~marsGrp.set(\ampMoon, ampMoon); + + ~encoderMars.do(_.set(6, (msg[2]/(2*pi))+0.5)); + ~encoderMars.do(_.set(7, ~modeElSign*(msg[3]/(2*pi))+~modeElPhase)); + + ~encoderPhobos.do(_.set(6, (msg[6]/(2*pi))+0.5)); + ~encoderPhobos.do(_.set(7, ~modeElSign*(msg[7]/(2*pi))+~modeElPhase)); + + ~encoderDeimos.do(_.set(6, (msg[9]/(2*pi))+0.5)); + ~encoderDeimos.do(_.set(7, ~modeElSign*(msg[10]/(2*pi))+~modeElPhase)); + + },'/Mars'); + + OSCdef.new(\jupiter, + { + arg msg; + var ampMoon; + var amp = (-1.2e-7*0.9*msg[1]).exp*1.05; + + ("Jupiter:" + msg).postln; + + if(~compareGate == 0, + {if(msg[4][0]==1, + {~jupiterP.set(\gate, 1);}, + {~jupiterP.set(\gate, 0);}); + + if(msg[4][1]==1, + {~jupiterG.set(\gate, 1);}, + {~jupiterG.set(\gate, 0);}); + + if(msg[4][2]==1, + {~jupiterT.set(\gate, 1);}, + {~jupiterT.set(\gate, 0);}); + + if(msg[4][3]==1, + {~jupiterW.set(\gate, 1);}, + {~jupiterW.set(\gate, 0);}); + + if(msg[4][4]==1, + {~ioP.set(\gate, 1); + ~europaP.set(\gate, 1); + ~ganymedeP.set(\gate, 1); + ~callistoP.set(\gate, 1); + }, + {~ioP.set(\gate, 0); + ~europaP.set(\gate, 0); + ~ganymedeP.set(\gate, 0); + ~callistoP.set(\gate, 0);}); + + if(amp>1.0, + {amp = 1.0}, + {amp = (-1.2e-7*0.9*msg[1]).exp*1.05}); + + if(0>amp, + {amp = 0.0}, + {amp = (-1.2e-7*0.9*msg[1]).exp*1.05}); + + ~jupiterGrp.set(\amp2, amp);}, + {~jupiterGrp.set(\amp2, 1.0);}); + + ampMoon = -4*(amp - 0.5).pow(2)+1; + ~jupiterGrp.set(\ampMoon, ampMoon); + + ~encoderJupiter.do(_.set(6, (msg[2]/(2*pi))+0.5)); + ~encoderJupiter.do(_.set(7, ~modeElSign*(msg[3]/(2*pi))+~modeElPhase)); + + ~encoderIo.do(_.set(6, (msg[6]/(2*pi))+0.5)); + ~encoderIo.do(_.set(7, ~modeElSign*(msg[7]/(2*pi))+~modeElPhase)); + + ~encoderEuropa.do(_.set(6, (msg[9]/(2*pi))+0.5)); + ~encoderEuropa.do(_.set(7, ~modeElSign*(msg[10]/(2*pi))+~modeElPhase)); + + ~encoderGanymede.do(_.set(6, (msg[12]/(2*pi))+0.5)); + ~encoderGanymede.do(_.set(7, ~modeElSign*(msg[13]/(2*pi))+~modeElPhase)); + + ~encoderCallisto.do(_.set(6, (msg[15]/(2*pi))+0.5)); + ~encoderCallisto.do(_.set(7, ~modeElSign*(msg[16]/(2*pi))+~modeElPhase)); + + },'/Jupiter'); + + + OSCdef.new(\saturn, + { + arg msg; + var ampMoon; + var amp = (-1.2e-7*0.9*msg[1]).exp*1.05; + + if(~compareGate == 0, + {if(msg[4][0]==1, + {~saturnP.set(\gate, 1);}, + {~saturnP.set(\gate, 0);}); + + if(msg[4][1]==1, + {~saturnG.set(\gate, 1);}, + {~saturnG.set(\gate, 0);}); + + if(msg[4][2]==1, + {~saturnT.set(\gate, 1);}, + {~saturnT.set(\gate, 0);}); + + if(msg[4][3]==1, + {~saturnW.set(\gate, 1);}, + {~saturnW.set(\gate, 0);}); + + if(msg[4][4]==1, + {~mimasP.set(\gate, 1); + ~enceladusP.set(\gate, 1); + ~tethysP.set(\gate, 1); + ~dioneP.set(\gate, 1); + ~rheaP.set(\gate, 1); + ~titanP.set(\gate, 1); + ~hyperionP.set(\gate, 1); + ~iapetusP.set(\gate, 1); + }, + {~mimasP.set(\gate, 0); + ~enceladusP.set(\gate, 0); + ~tethysP.set(\gate, 0); + ~dioneP.set(\gate, 0); + ~rheaP.set(\gate, 0); + ~titanP.set(\gate, 0); + ~hyperionP.set(\gate, 0); + ~iapetusP.set(\gate, 0); + }); + + if(msg[4][5]==1, + {~saturnR.set(\gate, 1);}, + {~saturnR.set(\gate, 0);}); + + if(amp>1.0, + {amp = 1.0}, + {amp = (-1.2e-7*0.9*msg[1]).exp*1.05}); + + ~saturnGrp.set(\amp2, amp);}, + {~saturnGrp.set(\amp2, 1.0);}); + + ampMoon = -4*(amp - 0.5).pow(2)+1; + ~saturnGrp.set(\ampMoon, ampMoon); + + ~encoderSaturn.do(_.set(6, (msg[2]/(2*pi))+0.5)); + ~encoderSaturn.do(_.set(7, ~modeElSign*(msg[3]/(2*pi))+~modeElPhase)); + + ~encoderDione.do(_.set(6, (msg[6]/(2*pi))+0.5)); + ~encoderDione.do(_.set(7, ~modeElSign*(msg[7]/(2*pi))+~modeElPhase)); + + ~encoderEnceladus.do(_.set(6, (msg[9]/(2*pi))+0.5)); + ~encoderEnceladus.do(_.set(7, ~modeElSign*(msg[10]/(2*pi))+~modeElPhase)); + + ~encoderHyperion.do(_.set(6, (msg[12]/(2*pi))+0.5)); + ~encoderHyperion.do(_.set(7, ~modeElSign*(msg[13]/(2*pi))+~modeElPhase)); + + ~encoderIapetus.do(_.set(6, (msg[15]/(2*pi))+0.5)); + ~encoderIapetus.do(_.set(7, ~modeElSign*(msg[16]/(2*pi))+~modeElPhase)); + + ~encoderMimas.do(_.set(6, (msg[18]/(2*pi))+0.5)); + ~encoderMimas.do(_.set(7, ~modeElSign*(msg[19]/(2*pi))+~modeElPhase)); + + ~encoderRhea.do(_.set(6, (msg[21]/(2*pi))+0.5)); + ~encoderRhea.do(_.set(7, ~modeElSign*(msg[22]/(2*pi))+~modeElPhase)); + + ~encoderTethys.do(_.set(6, (msg[24]/(2*pi))+0.5)); + ~encoderTethys.do(_.set(7, ~modeElSign*(msg[25]/(2*pi))+~modeElPhase)); + + ~encoderTitan.do(_.set(6, (msg[27]/(2*pi))+0.5)); + ~encoderTitan.do(_.set(7, ~modeElSign*(msg[28]/(2*pi))+~modeElPhase)); + + },'/Saturn'); + + + + + OSCdef.new(\uranus, + { + arg msg; + var ampMoon; + var amp = (-6.7e-7*0.7*msg[1]).exp*1.1; + + if(~compareGate == 0, + {if(msg[4][0]==1, + {~uranusP.set(\gate, 1);}, + {~uranusP.set(\gate, 0);}); + + if(msg[4][1]==1, + {~uranusG.set(\gate, 1);}, + {~uranusG.set(\gate, 0);}); + + if(msg[4][2]==1, + {~uranusT.set(\gate, 1);}, + {~uranusT.set(\gate, 0);}); + + if(msg[4][3]==1, + {~uranusW.set(\gate, 1);}, + {~uranusW.set(\gate, 0);}); + + if(msg[4][4]==1, + {~arielP.set(\gate, 1); + ~mirandaP.set(\gate, 1); + ~oberonP.set(\gate, 1); + ~titaniaP.set(\gate, 1); + ~umbrielP.set(\gate, 1); + }, + {~arielP.set(\gate, 0); + ~mirandaP.set(\gate, 0); + ~oberonP.set(\gate, 0); + ~titaniaP.set(\gate, 0); + ~umbrielP.set(\gate, 0); + }); + + if(amp>1.0, + {amp = 1.0}, + {amp = (-6.7e-7*0.7*msg[1]).exp*1.1}); + + ~uranusGrp.set(\amp2, amp);}, + {~uranusGrp.set(\amp2, 1.0);}); + + ampMoon = -4*(amp - 0.5).pow(2)+1; + ~uranusGrp.set(\ampMoon, ampMoon); + + ~encoderUranus.do(_.set(6, (msg[2]/(2*pi))+0.5)); + ~encoderUranus.do(_.set(7, ~modeElSign*(msg[3]/(2*pi))+~modeElPhase)); + + ~encoderAriel.do(_.set(6, (msg[6]/(2*pi))+0.5)); + ~encoderAriel.do(_.set(7, ~modeElSign*(msg[7]/(2*pi))+~modeElPhase)); + + ~encoderMiranda.do(_.set(6, (msg[9]/(2*pi))+0.5)); + ~encoderMiranda.do(_.set(7, ~modeElSign*(msg[10]/(2*pi))+~modeElPhase)); + + ~encoderOberon.do(_.set(6, (msg[12]/(2*pi))+0.5)); + ~encoderOberon.do(_.set(7, ~modeElSign*(msg[13]/(2*pi))+~modeElPhase)); + + ~encoderTitania.do(_.set(6, (msg[15]/(2*pi))+0.5)); + ~encoderTitania.do(_.set(7, ~modeElSign*(msg[16]/(2*pi))+~modeElPhase)); + + ~encoderUmbriel.do(_.set(6, (msg[18]/(2*pi))+0.5)); + ~encoderUmbriel.do(_.set(7, ~modeElSign*(msg[19]/(2*pi))+~modeElPhase)); + + },'/Uranus'); + + OSCdef.new(\neptune, + { + arg msg; + var ampMoon; + var amp = (-7.7e-7*0.8*msg[1]).exp*1.15; + + if(~compareGate == 0, + {if(msg[4][0]==1, + {~neptuneP.set(\gate, 1);}, + {~neptuneP.set(\gate, 0);}); + + if(msg[4][1]==1, + {~neptuneG.set(\gate, 1);}, + {~neptuneG.set(\gate, 0);}); + + if(msg[4][2]==1, + {~neptuneT.set(\gate, 1);}, + {~neptuneT.set(\gate, 0);}); + + if(msg[4][3]==1, + {~neptuneW.set(\gate, 1);}, + {~neptuneW.set(\gate, 0);}); + + if(msg[4][4]==1, + {~tritonP.set(\gate, 1);}, + {~tritonP.set(\gate, 0);}); + + if(amp>1.0, + {amp = 1.0}, + {amp = (-7.7e-7*0.8*msg[1]).exp*1.15}); + + ~neptuneGrp.set(\amp2, amp);}, + {~neptuneGrp.set(\amp2, 1.0);}); + + ampMoon = -4*(amp - 0.5).pow(2)+1; + ~neptuneGrp.set(\ampMoon, ampMoon); + + ~encoderNeptune.do(_.set(6, (msg[2]/(2*pi))+0.5)); + ~encoderNeptune.do(_.set(7, ~modeElSign*(msg[3]/(2*pi))+~modeElPhase)); + + ~encoderTriton.do(_.set(6, (msg[6]/(2*pi))+0.5)); + ~encoderTriton.do(_.set(7, ~modeElSign*(msg[7]/(2*pi))+~modeElPhase)); + + },'/Neptune'); + + OSCdef.new(\Overview, + { + arg msg; + + //msg[1] = array of gates + //msg[1][0] = all gate + //msg[1][1] = mercury + //msg[1][2] = venus + //msg[1][3] = earth + //msg[1][4] = mars + //... + + ("Solar:" + msg).postln; + + if((msg[1][0] != 0 or: msg[1][1] != 0 or: msg[1][2] != 0 or: msg[1][3] != 0 or: msg[1][4] != 0 or: msg[1][5] != 0 or: msg[1][6] != 0 or: msg[1][7] != 0), + {~compareGate=1;}, + {~compareGate=0;}); + + ("~compareGate:" + ~compareGate).postln; + + if(msg[1][0] == 1, + {~mercuryPoof.set(\gate, 1);}, + {~mercuryPoof.set(\gate, 0);}); + + if(msg[1][1] == 1, + {~venusPoof.set(\gate, 1);}, + {~venusPoof.set(\gate, 0);}); + + if(msg[1][2] == 1, + {~earthPoof.set(\gate, 1);}, + {~earthPoof.set(\gate, 0);}); + + if(msg[1][3] == 1, + {~marsPoof.set(\gate, 1);}, + {~marsPoof.set(\gate, 0);}); + + if(msg[1][4] == 1, + {~jupiterPoof.set(\gate, 1);}, + {~jupiterPoof.set(\gate, 0);}); + + if(msg[1][5] == 1, + {~saturnPoof.set(\gate, 1);}, + {~saturnPoof.set(\gate, 0);}); + + if(msg[1][6] == 1, + {~uranusPoof.set(\gate, 1);}, + {~uranusPoof.set(\gate, 0);}); + + if(msg[1][7] == 1, + {~neptunePoof.set(\gate, 1);}, + {~neptunePoof.set(\gate, 0);}); + + },'/Overview'); + + OSCdef.new(\compare, + { + arg msg; + ("compare settings:" + msg[3]).postln; + + //msg[1] = first planet to compare + //msg[2] = second planet to compare + //msg[3] = [ + //msg[3][0] = size/day + //msg[3][1] = gravity + //msg[3][2] = temperature + //msg[3][3] = atmosphere + //msg[3][4] = moons + //msg[3][5] = rings + + ("Compare:" + msg).postln; + + + ("First: " + msg[1]).postln; + ("Second: " + msg[2]).postln; + + if(msg[1] != 0 or: msg[2] != 0, + {~compareGate=1;}, + {~compareGate=0;}); + + + if(msg[1] == 1 or: {msg[2] == 1}, + {if(msg[3][0]==1, + {~mercuryP.set(\gate, 1);}, + {~mercuryP.set(\gate, 0);}); + + if(msg[3][1]==1, + {~mercuryG.set(\gate, 1);}, + {~mercuryG.set(\gate, 0);}); + + if(msg[3][2]==1, + {~mercuryT.set(\gate, 1);}, + {~mercuryT.set(\gate, 0);}); + + if(msg[3][3]==1, + {~mercuryW.set(\gate, 1);}, + {~mercuryW.set(\gate, 0);});}, + + {~mercuryGrp.set(\gate, 0);}); + + if(msg[1] == 2 or: {msg[2] == 2}, + {if(msg[3][0]==1, + {~venusP.set(\gate, 1);}, + {~venusP.set(\gate, 0);}); + + if(msg[3][1]==1, + {~venusG.set(\gate, 1);}, + {~venusG.set(\gate, 0);}); + + if(msg[3][2]==1, + {~venusT.set(\gate, 1);}, + {~venusT.set(\gate, 0);}); + + if(msg[3][3]==1, + {~venusW.set(\gate, 1);}, + {~venusW.set(\gate, 0);});}, + + {~venusGrp.set(\gate, 0);}); + + if(msg[1] == 3 or: {msg[2] == 3}, + {if(msg[3][0]==1, + {~earthP.set(\gate, 1);}, + {~earthP.set(\gate, 0);}); + + if(msg[3][1]==1, + {~earthG.set(\gate, 1);}, + {~earthG.set(\gate, 0);}); + + if(msg[3][2]==1, + {~earthT.set(\gate, 1);}, + {~earthT.set(\gate, 0);}); + + if(msg[3][3]==1, + {~earthW.set(\gate, 1);}, + {~earthW.set(\gate, 0);}); + + if(msg[3][4]==1, + {~moonP.set(\gate, 1);}, + {~moonP.set(\gate, 0);});}, + + {~earthGrp.set(\gate, 0);}); + + if(msg[1] == 4 or: {msg[2] == 4}, + {if(msg[3][0]==1, + {~marsP.set(\gate, 1);}, + {~marsP.set(\gate, 0);}); + + if(msg[3][1]==1, + {~marsG.set(\gate, 1);}, + {~marsG.set(\gate, 0);}); + + if(msg[3][2]==1, + {~marsT.set(\gate, 1);}, + {~marsT.set(\gate, 0);}); + + if(msg[3][3]==1, + {~marsW.set(\gate, 1);}, + {~marsW.set(\gate, 0);}); + + if(msg[3][4]==1, + {~phobosP.set(\gate, 1); + ~deimosP.set(\gate, 1); + }, + {~phobosP.set(\gate, 0); + ~deimosP.set(\gate, 0);});}, + + {~marsGrp.set(\gate, 0);}); + + if(msg[1] == 5 or: {msg[2] == 5}, + {if(msg[3][0]==1, + {~jupiterP.set(\gate, 1);}, + {~jupiterP.set(\gate, 0);}); + + if(msg[3][1]==1, + {~jupiterG.set(\gate, 1);}, + {~jupiterG.set(\gate, 0);}); + + if(msg[3][2]==1, + {~jupiterT.set(\gate, 1);}, + {~jupiterT.set(\gate, 0);}); + + if(msg[3][3]==1, + {~jupiterW.set(\gate, 1);}, + {~jupiterW.set(\gate, 0);}); + + if(msg[3][4]==1, + {~ioP.set(\gate, 1); + ~europaP.set(\gate, 1); + ~ganymedeP.set(\gate, 1); + ~callistoP.set(\gate, 1); + }, + {~ioP.set(\gate, 0); + ~europaP.set(\gate, 0); + ~ganymedeP.set(\gate, 0); + ~callistoP.set(\gate, 0);});}, + + {~jupiterGrp.set(\gate, 0);}); + + + if(msg[1] == 6 or: {msg[2] == 6}, + {if(msg[3][0]==1, + {~saturnP.set(\gate, 1);}, + {~saturnP.set(\gate, 0);}); + + if(msg[3][1]==1, + {~saturnG.set(\gate, 1);}, + {~saturnG.set(\gate, 0);}); + + if(msg[3][2]==1, + {~saturnT.set(\gate, 1);}, + {~saturnT.set(\gate, 0);}); + + if(msg[3][3]==1, + {~saturnW.set(\gate, 1);}, + {~saturnW.set(\gate, 0);}); + + if(msg[3][4]==1, + {~mimasP.set(\gate, 1); + ~enceladusP.set(\gate, 1); + ~tethysP.set(\gate, 1); + ~dioneP.set(\gate, 1); + ~rheaP.set(\gate, 1); + ~titanP.set(\gate, 1); + ~hyperionP.set(\gate, 1); + ~iapetusP.set(\gate, 1); + }, + {~mimasP.set(\gate, 0); + ~enceladusP.set(\gate, 0); + ~tethysP.set(\gate, 0); + ~dioneP.set(\gate, 0); + ~rheaP.set(\gate, 0); + ~titanP.set(\gate, 0); + ~hyperionP.set(\gate, 0); + ~iapetusP.set(\gate, 0); + }); + + if(msg[3][5]==1, + {~saturnR.set(\gate, 1);}, + {~saturnR.set(\gate, 0);});}, + {~saturnGrp.set(\gate, 0);}); + + + if(msg[1] == 7 or: {msg[2] == 7}, + {if(msg[3][0]==1, + {~uranusP.set(\gate, 1);}, + {~uranusP.set(\gate, 0);}); + + if(msg[3][1]==1, + {~uranusG.set(\gate, 1);}, + {~uranusG.set(\gate, 0);}); + + if(msg[3][2]==1, + {~uranusT.set(\gate, 1);}, + {~uranusT.set(\gate, 0);}); + + if(msg[3][3]==1, + {~uranusW.set(\gate, 1);}, + {~uranusW.set(\gate, 0);}); + + if(msg[3][4]==1, + {~arielP.set(\gate, 1); + ~mirandaP.set(\gate, 1); + ~oberonP.set(\gate, 1); + ~titaniaP.set(\gate, 1); + ~umbrielP.set(\gate, 1); + }, + {~arielP.set(\gate, 0); + ~mirandaP.set(\gate, 0); + ~oberonP.set(\gate, 0); + ~titaniaP.set(\gate, 0); + ~umbrielP.set(\gate, 0); + });}, + {~uranusGrp.set(\gate, 0);}); + + if(msg[1] == 8 or: {msg[2] == 8}, + {if(msg[3][0]==1, + {~neptuneP.set(\gate, 1);}, + {~neptuneP.set(\gate, 0);}); + + if(msg[3][1]==1, + {~neptuneG.set(\gate, 1);}, + {~neptuneG.set(\gate, 0);}); + + if(msg[3][2]==1, + {~neptuneT.set(\gate, 1);}, + {~neptuneT.set(\gate, 0);}); + + if(msg[3][3]==1, + {~neptuneW.set(\gate, 1);}, + {~neptuneW.set(\gate, 0);}); + + if(msg[3][4]==1, + {~tritonP.set(\gate, 1);}, + {~tritonP.set(\gate, 0);});}, + {~neptuneGrp.set(\gate, 0);}); + + },'/Compare'); + + }; + + // Start routine + ~startRoutine = Routine({ + + loadData.value; + "--Loaded the data--".postln; + 0.1.wait; + loadSynthDefs.value; + "--Loaded the synths--".postln; + 0.2.wait; + loadAmbiGroups.value; + "--Loaded the ambisonics--".postln; + 0.1.wait; + initiateSynths.value; + "--Initiated the synths--".postln; + 0.1.wait; + loadDecoder.value; + "--Loaded the decoder--".postln; + 0.1.wait; + loadOSC.value; + "--Loaded the OSCdefs--".postln; + + "---------- Sonification is ready ----------".postln; + + }); + + ~startRoutine.play(AppClock); + +} +) \ No newline at end of file diff --git a/data/assets/modules/telemetry/sonification/planets.asset b/data/assets/modules/telemetry/sonification/planets.asset new file mode 100644 index 0000000000..1de04d5032 --- /dev/null +++ b/data/assets/modules/telemetry/sonification/planets.asset @@ -0,0 +1,81 @@ +-- For more information about sonification in OpenSpace and how to use it, see the +-- documentation: +-- https://docs.openspaceproject.com/latest/creating-data-assets/modules/telemetry/sonification.html + +asset.require("scene/solarsystem/planets/planets") + +asset.onInitialize(function () + -- Note that the planets need to be in this order + local planets = { + { + Name = "Mercury" + }, + { + Name = "Venus" + }, + { + Name = "Earth", + Moons = { + "Moon" + } + }, + { + Name = "Mars", + Moons = { + "Phobos", + "Deimos" + } + }, + { + Name = "Jupiter", + Moons = { + "Io", + "Europa", + "Ganymede", + "Callisto" + } + }, + { + Name = "Saturn", + Moons = { + "Dione", + "Enceladus", + "Hyperion", + "Iapetus", + "Mimas", + "Rhea", + "Tethys", + "Titan" + } + }, + { + Name = "Uranus", + Moons = { + "Ariel", + "Miranda", + "Oberon", + "Titania", + "Umbriel" + } + }, + { + Name = "Neptune", + Moons = { + "Triton", + "Nereid" + } + } + } + + openspace.sonification.addPlanets(planets) +end) + + +asset.meta = { + Name = "PlanetSonification planets", + Version = "1.0", + Description = "The list of planets in the PlanetSonification", + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/nightsky/altaz.asset b/data/assets/nightsky/altaz.asset index 1ec3c7f65b..494ca1aeeb 100644 --- a/data/assets/nightsky/altaz.asset +++ b/data/assets/nightsky/altaz.asset @@ -2,6 +2,14 @@ local earthAsset = asset.require("scene/solarsystem/planets/earth/earth") +local labels = asset.resource({ + Name = "AltAz Label Files", + Type = "HttpSynchronization", + Identifier = "alt_az_labels", + Version = 1 +}) + + local AltAzGridPosition = { Identifier = "AltAzGridPosition", Parent = earthAsset.Earth.Identifier, @@ -52,6 +60,7 @@ local AltAzGrid = { LineWidth = 2.0, RenderBinMode = "PostDeferredTransparent" }, + Tag = { "nightsky_marking" }, GUI = { Name = "Altitude-Azimuth Grid", Description = [[A local Altitude/Azimuth grid centered around your position on a @@ -62,6 +71,39 @@ local AltAzGrid = { } } +local AltAzGridLabels = { + Identifier = "AltAzGridLabels", + Parent = AltAzGridPosition.Identifier, + Transform = { + Rotation = { + Type = "StaticRotation", + Rotation = { -math.pi / 2.0, math.pi, 0.0 } + } + }, + Renderable = { + Type = "RenderablePointCloud", + Enabled = false, + Labels = { + Enabled = true, + File = labels .. "eclip.label", + Color = { 0.5, 0.5, 0.5 }, + FaceCamera = false, + Size = 14.8, + MinMaxSize = { 2, 70 }, + Unit = "pc", + }, + Opacity = 0.65, + RenderBinMode = "PostDeferredTransparent" + }, + Tag = { "nightsky_marking" }, + GUI = { + Name = "Altitude-Azimuth Grid Labels", + Description = [[Labels for the Altitude-Azimuth Grid]], + Path = "/Night Sky/Coordinate Systems/Altitude-Azimuth" + } +} + + local ShowAltaz = { Identifier = "os.nightsky.ShowAltaz", Name = "Show Alt/Az grid", @@ -105,6 +147,7 @@ local ToggleAltaz = { asset.onInitialize(function() openspace.addSceneGraphNode(AltAzGridPosition) openspace.addSceneGraphNode(AltAzGrid) + openspace.addSceneGraphNode(AltAzGridLabels) openspace.action.registerAction(ShowAltaz) openspace.action.registerAction(HideAltaz) openspace.action.registerAction(ToggleAltaz) @@ -115,12 +158,14 @@ asset.onDeinitialize(function() openspace.action.removeAction(ToggleAltaz) openspace.action.removeAction(HideAltaz) openspace.action.removeAction(ShowAltaz) + openspace.removeSceneGraphNode(AltAzGridLabels) openspace.removeSceneGraphNode(AltAzGrid) openspace.removeSceneGraphNode(AltAzGridPosition) end) asset.export(AltAzGridPosition) asset.export(AltAzGrid) +asset.export(AltAzGridLabels) asset.export("ShowAltaz", ShowAltaz.Identifier) asset.export("HideAltaz", HideAltaz.Identifier) asset.export("ToggleAltaz", ToggleAltaz.Identifier) diff --git a/data/assets/nightsky/cardinal_directions.asset b/data/assets/nightsky/cardinal_directions.asset index 026bc3ca2c..437879e5b6 100644 --- a/data/assets/nightsky/cardinal_directions.asset +++ b/data/assets/nightsky/cardinal_directions.asset @@ -56,8 +56,10 @@ local CardinalDirectionSphere = { Texture = textures .. "nesw_red.png", Orientation = "Inside", MirrorTexture = true, - RenderBinMode = "PostDeferredTransparent" + RenderBinMode = "PostDeferredTransparent", + DisableDepth = true }, + Tag = {"nightsky_marking"}, GUI = { Name = "Cardinal Directions", Description = [[A textured sphere showing the cardinal directions. diff --git a/data/assets/nightsky/ecliptic_band.asset b/data/assets/nightsky/ecliptic_band.asset index f2f268c274..03ef0a2b69 100644 --- a/data/assets/nightsky/ecliptic_band.asset +++ b/data/assets/nightsky/ecliptic_band.asset @@ -6,7 +6,7 @@ local textures = asset.resource({ Name = "Ecliptic Band Textures", Type = "HttpSynchronization", Identifier = "ecliptic_band_textures", - Version = 2 + Version = 3 }) @@ -34,9 +34,10 @@ local EclipticLine = { Opacity = 0.8, Color = { 0.5, 0.24, 0.24 }, LineWidth = 4.0, - GridSegments = { 1, 1 }, + GridSegments = {1 , 1}, Enabled = asset.enabled }, + Tag = { "nightsky_marking" }, GUI = { Name = "Ecliptic", Description = "A line representation of the Ecliptic plane.", @@ -55,14 +56,16 @@ local EclipticBand = { }, Renderable = { Type = "RenderableSphereImageLocal", - Texture = textures .. "band2x.png", + Texture = textures .. "ecliptic.png", Size = 9.46377307652E17, Segments = 50, DisableFadeInOut = true, Orientation = "Inside", - Opacity = 0.05, - Enabled = asset.enabled + Opacity = 0.99, + Enabled = asset.enabled, + RenderBinMode = "PostDeferredTransparent", }, + Tag = { "nightsky_marking" }, GUI = { Name = "Ecliptic Band", Description = "A band representation of the Ecliptic plane.", @@ -128,6 +131,27 @@ local ToggleEclipticBand = { IsLocal = false } +local SetBandWhiteAction = { + Identifier = "os.nightsky.SetEclipticBandWhite", + Name = "Set Ecliptic Band to black and white", + Command = [[ + openspace.setPropertyValueSingle("Scene.EclipticBand.Renderable.Texture", "]] .. textures:gsub("\\","/") .. [[eclipticWhite.png") + ]], + Documentation = "Sets the color of the ecliptic band to white", + GuiPath = "/Night Sky/Lines and Grids/Ecliptic", + IsLocal = false +} + +local SetBandColorsAction = { + Identifier = "os.nightsky.SetEclipticBandColors", + Name = "Set Ecliptic Band to colors", + Command = [[ + openspace.setPropertyValueSingle("Scene.EclipticBand.Renderable.Texture", "]] .. textures:gsub("\\","/") .. [[ecliptic.png") + ]], + Documentation = "Sets the color of the ecliptic band to colored", + GuiPath = "/Night Sky/Lines and Grids/Ecliptic", + IsLocal = false +} asset.onInitialize(function() openspace.addSceneGraphNode(EclipticLine) @@ -138,9 +162,13 @@ asset.onInitialize(function() openspace.action.registerAction(ShowEclipticBand) openspace.action.registerAction(HideEclipticBand) openspace.action.registerAction(ToggleEclipticBand) + openspace.action.registerAction(SetBandWhiteAction) + openspace.action.registerAction(SetBandColorsAction) end) asset.onDeinitialize(function() + openspace.action.removeAction(SetBandColorsAction) + openspace.action.removeAction(SetBandWhiteAction) openspace.action.removeAction(ToggleEclipticBand) openspace.action.removeAction(HideEclipticBand) openspace.action.removeAction(ShowEclipticBand) @@ -159,6 +187,8 @@ asset.export("ToggleEclipticLine", ToggleEclipticLine.Identifier) asset.export("ShowEclipticBand", ShowEclipticBand.Identifier) asset.export("HideEclipticBand", HideEclipticBand.Identifier) asset.export("ToggleEclipticBand", ToggleEclipticBand.Identifier) +asset.export("SetBandWhiteAction", SetBandWhiteAction.Identifier) +asset.export("SetBandColorsAction", SetBandColorsAction.Identifier) @@ -166,7 +196,7 @@ asset.meta = { Name = "Ecliptic Band/Line", Description = [[A line and band representation of the Ecliptic plane, including actions to toggle, hide and show each of them.]], - Author = "OpenSpace Team", + Author = "OpenSpace Team / Ken Murphy", URL = "http://openspaceproject.com", License = "MIT license" } diff --git a/data/assets/nightsky/equatorial_band.asset b/data/assets/nightsky/equatorial_band.asset index b72e01e5df..07bbd74213 100644 --- a/data/assets/nightsky/equatorial_band.asset +++ b/data/assets/nightsky/equatorial_band.asset @@ -27,9 +27,10 @@ local EquatorialLine = { Opacity = 0.8, Color = { 0.6, 0.6, 0.2 }, LineWidth = 4.0, - GridSegments = { 1, 1 }, + GridSegments = {1, 1}, Enabled = asset.enabled }, + Tag = { "nightsky_marking" }, GUI = { Name = "Celestial Equator", Description = "A line representation of the Equatorial plane.", diff --git a/data/assets/nightsky/galactic_band.asset b/data/assets/nightsky/galactic_band.asset index 79752a29aa..7750e84ab4 100644 --- a/data/assets/nightsky/galactic_band.asset +++ b/data/assets/nightsky/galactic_band.asset @@ -2,8 +2,8 @@ local transforms = asset.require("scene/solarsystem/sun/transforms") -local GalacticLine = { - Identifier = "GalacticLine", +local GalacticEquator = { + Identifier = "GalacticEquator", Parent = transforms.SolarSystemBarycenter.Name, Transform = { Scale = { @@ -19,6 +19,7 @@ local GalacticLine = { GridSegments = { 1, 1 }, Enabled = asset.enabled }, + Tag = { "nightsky_marking" }, GUI = { Name = "Galactic Equator", Description = "A line representation of the Galactic Equator plane.", @@ -27,58 +28,61 @@ local GalacticLine = { } -local ShowGalacticBand = { - Identifier = "os.nightsky.ShowGalacticBand", - Name = "Show galactic band", +local ShowGalacticEquator = { + Identifier = "os.nightsky.ShowGalacticEquator", + Name = "Show galactic equator", Command = [[ - openspace.fadeIn("Scene.GalacticBand.Renderable") + openspace.fadeIn("Scene.GalacticEquator.Renderable") ]], - Documentation = "Shows the galactic band", + Documentation = "Shows the galactic equator", GuiPath = "/Night Sky/Lines and Grids/Show and Hide", IsLocal = false } -local HideGalacticBand = { - Identifier = "os.nightsky.HideGalacticBand", - Name = "Hide galactic band", +local HideGalacticEquator = { + Identifier = "os.nightsky.HideGalacticEquator", + Name = "Hide galactic equator", Command = [[ - openspace.fadeOut("Scene.GalacticBand.Renderable") + openspace.fadeOut("Scene.GalacticEquator.Renderable") ]], - Documentation = "Hides the galactic band", + Documentation = "Hides the galactic equator", GuiPath = "/Night Sky/Lines and Grids/Show and Hide", IsLocal = false } -local ToggleGalacticBand = { - Identifier = "os.nightsky.ToggleGalacticBand", - Name = "Toggle galactic equator line", - Command = "openspace.toggleFade('Scene.GalacticBand.Renderable')", - Documentation = "Toggles the galactic equator line visibilty", +local ToggleGalacticEquator = { + Identifier = "os.nightsky.ToggleGalacticEquator", + Name = "Toggle galactic equator", + Command = "openspace.toggleFade('Scene.GalacticEquator.Renderable')", + Documentation = "Toggles the galactic equator visibilty", GuiPath = "/Night Sky/Lines and Grids", IsLocal = false } asset.onInitialize(function() - openspace.addSceneGraphNode(GalacticLine) - openspace.action.registerAction(ShowGalacticBand) - openspace.action.registerAction(HideGalacticBand) + openspace.addSceneGraphNode(GalacticEquator) + openspace.action.registerAction(ShowGalacticEquator) + openspace.action.registerAction(HideGalacticEquator) + openspace.action.registerAction(ToggleGalacticEquator) end) asset.onDeinitialize(function() - openspace.action.removeAction(HideGalacticBand) - openspace.action.removeAction(ShowGalacticBand) - openspace.removeSceneGraphNode(GalacticLine) + openspace.action.removeAction(ToggleGalacticEquator) + openspace.action.removeAction(HideGalacticEquator) + openspace.action.removeAction(ShowGalacticEquator) + openspace.removeSceneGraphNode(GalacticEquator) end) -asset.export(GalacticLine) -asset.export("ShowGalacticBand", ShowGalacticBand.Identifier) -asset.export("HideGalacticBand", HideGalacticBand.Identifier) +asset.export(GalacticEquator) +asset.export("ShowGalacticEquator", ShowGalacticEquator.Identifier) +asset.export("HideGalacticEquator", HideGalacticEquator.Identifier) +asset.export("ToggleGalacticEquator", ToggleGalacticEquator.Identifier) asset.meta = { - Name = "Galactic Line", + Name = "Galactic Equator", Description = [[A line representation of the Galactic Equator plane, including actions to toggle, hide and show it.]], Author = "OpenSpace Team", diff --git a/data/assets/nightsky/light_pollution.asset b/data/assets/nightsky/light_pollution.asset index e4f502c0c8..0232e76ea3 100644 --- a/data/assets/nightsky/light_pollution.asset +++ b/data/assets/nightsky/light_pollution.asset @@ -42,8 +42,7 @@ local LightPollutionSphere = { Orientation = "Inside", MirrorTexture = true, FadeOutThreshold = 1.00, - RenderBinMode = "PostDeferredTransparent", - Enabled = asset.enabled + RenderBinMode = "PostDeferredTransparent" }, GUI = { Name = "Light Pollution Sphere", diff --git a/data/assets/nightsky/meridian.asset b/data/assets/nightsky/meridian.asset index df007e1367..c1481b9238 100644 --- a/data/assets/nightsky/meridian.asset +++ b/data/assets/nightsky/meridian.asset @@ -22,6 +22,7 @@ local MeridianPosition = { UseCamera = true } }, + Tag = { "nightsky_marking" }, GUI = { Name = "Local Meridian Position", Path = "/Night Sky/Coordinate Systems/Altitude-Azimuth", @@ -44,9 +45,9 @@ local MeridianPlane = { Color = { 0.4, 0.8, 0.4 }, LineWidth = 6.0, GridSegments = { 1, 1 }, - Enabled = asset.enabled, - RenderBinMode = "PostDeferredTransparent" + Enabled = asset.enabled }, + Tag = { "nightsky_marking" }, GUI = { Name = "Local Meridian", Description = [[A line representation of the Local Meridian]], diff --git a/data/assets/nightsky/nightsky.asset b/data/assets/nightsky/nightsky.asset index b2f428af7b..c66381aa06 100644 --- a/data/assets/nightsky/nightsky.asset +++ b/data/assets/nightsky/nightsky.asset @@ -9,6 +9,10 @@ asset.require("./zenith", false) asset.require("./planets", false) asset.require("actions/nightsky/camera", false) asset.require("actions/nightsky/daytime", false) +asset.require("actions/nightsky/createsuntrails", false) +asset.require("actions/nightsky/misc", false) +asset.require("actions/nightsky/position", false) +asset.require("actions/time", false) diff --git a/data/assets/nightsky/planets.asset b/data/assets/nightsky/planets.asset index 8239d168e8..4a39cb24e5 100644 --- a/data/assets/nightsky/planets.asset +++ b/data/assets/nightsky/planets.asset @@ -13,17 +13,33 @@ local textures = asset.resource({ Version = 1 }) +local csv = asset.resource({ + Name = "Zero Point Data", + Type = "HttpSynchronization", + Identifier = "zeropoint_data", + Version = 1 +}) + local Mercury = { Identifier = "NightSkyMercury", Parent = mercury.MercuryBarycenter.Identifier, Renderable = { - Type = "RenderablePlaneImageLocal", - Billboard = true, + Type = "RenderablePointCloud", + File = csv .. "zeropointdata.csv", + Coloring = { + FixedColor = { 0.608, 0.604, 0.455 } + }, + Texture = { + File = textures .. "glare.png" + }, + SizeSettings = { + ScaleFactor = 10, + ScaleExponent = 15, + MaxSize = 0.209, + EnableMaxSizeControl = true + }, Enabled = asset.enabled, - Size = 2439700 * 500, - Texture = textures .. "glare.png", - MultiplyColor = { 0.608, 0.604, 0.455 }, DimInAtmosphere = true, RenderBinMode = "PostDeferredTransparent" }, @@ -41,12 +57,21 @@ local Venus = { Identifier = "NightSkyVenus", Parent = venus.VenusBarycenter.Identifier, Renderable = { - Type = "RenderablePlaneImageLocal", + Type = "RenderablePointCloud", + File = csv .. "zeropointdata.csv", + Coloring = { + FixedColor = { 1.0 , 0.992, 0.757 } + }, + Texture = { + File = textures .. "glare.png" + }, + SizeSettings = { + ScaleFactor = 10, + ScaleExponent = 15, + MaxSize = 1.14, + EnableMaxSizeControl = true + }, Enabled = asset.enabled, - Billboard = true, - Size = 6051900 * 700, - Texture = textures .. "glare.png", - MultiplyColor = { 1.0 , 0.992, 0.757 }, DimInAtmosphere = true, RenderBinMode = "PostDeferredTransparent" }, @@ -64,12 +89,21 @@ local Mars = { Identifier = "NightSkyMars", Parent = mars.MarsBarycenter.Identifier, Renderable = { - Type = "RenderablePlaneImageLocal", + Type = "RenderablePointCloud", + File = csv .. "zeropointdata.csv", + Coloring = { + FixedColor = { 0.756, 0.267, 0.054 } + }, + Texture = { + File = textures .. "glare.png" + }, + SizeSettings = { + ScaleFactor = 10, + ScaleExponent = 15, + MaxSize = 0.404, --mars max angular size / 62 + EnableMaxSizeControl = true + }, Enabled = asset.enabled, - Billboard = true, - Size = 3396190 * 1000, - Texture = textures .. "glare.png", - MultiplyColor = { 0.756, 0.267, 0.054 }, DimInAtmosphere = true, RenderBinMode = "PostDeferredTransparent" }, @@ -85,12 +119,21 @@ local Jupiter = { Identifier = "NightSkyJupiter", Parent = jupiter.JupiterBarycenter.Identifier, Renderable = { - Type = "RenderablePlaneImageLocal", + Type = "RenderablePointCloud", + File = csv .. "zeropointdata.csv", + Coloring = { + FixedColor = { 0.608, 0.604, 0.455 }, + }, + Texture = { + File = textures .. "glare.png" + }, + SizeSettings = { + ScaleFactor = 10, + ScaleExponent = 15, + MaxSize = 0.82, + EnableMaxSizeControl = true + }, Enabled = asset.enabled, - Billboard = true, - Size = 71492000 * 400, - Texture = textures .. "glare.png", - MultiplyColor = { 0.608, 0.604, 0.455 }, DimInAtmosphere = true, RenderBinMode = "PostDeferredTransparent" }, @@ -108,12 +151,19 @@ local Saturn = { Identifier = "NightSkySaturn", Parent = saturn.SaturnBarycenter.Identifier, Renderable = { - Type = "RenderablePlaneImageLocal", + Type = "RenderablePointCloud", + File = csv .. "zeropointdata.csv", + Coloring = { + FixedColor = { 0.85098, 0.843137, 0.619608 }, + }, + Texture = { + File = textures .. "glare.png" + }, + SizeSettings = { + MaxSize = 0.332, + EnableMaxSizeControl = true + }, Enabled = asset.enabled, - Billboard = true, - Size = 60268000 * 500, - Texture = textures .. "glare.png", - MultiplyColor = { 0.608, 0.604, 0.455 }, DimInAtmosphere = true, RenderBinMode = "PostDeferredTransparent" }, diff --git a/data/assets/nightsky/zenith.asset b/data/assets/nightsky/zenith.asset index 1104c34124..abc46fc419 100644 --- a/data/assets/nightsky/zenith.asset +++ b/data/assets/nightsky/zenith.asset @@ -31,6 +31,7 @@ local ZenithPosition = { UseCamera = true } }, + Tag = { "nightsky_marking" }, GUI = { Name = "Zenith Position", Path = "/Night Sky/Coordinate Systems/Altitude-Azimuth", @@ -56,6 +57,7 @@ local ZenithDot = { Texture = textures .. "point3A.png", BlendMode = "Additive" }, + Tag = { "nightsky_marking" }, GUI = { Name = "Zenith", Description = [[A dot representation of the Local Zenith, based on the camera's diff --git a/data/assets/scene/digitaluniverse/2dF.asset b/data/assets/scene/digitaluniverse/2dF.asset index 0297cc93db..aa61f71135 100644 --- a/data/assets/scene/digitaluniverse/2dF.asset +++ b/data/assets/scene/digitaluniverse/2dF.asset @@ -42,6 +42,7 @@ local Object = { GUI = { Name = "2dF Galaxies", Path = "/Universe/Deep Sky Surveys", + Focusable = false, Description = [[The Two-degree Field (2dF) Survey was a project designed to map portions of the extragalactic universe. The 2dF survey has three main components: the North Galactic Pole strip, the South Galactic Pole strip, and the random fields diff --git a/data/assets/scene/digitaluniverse/2mass.asset b/data/assets/scene/digitaluniverse/2mass.asset index f05c1d84d0..f48d163da2 100644 --- a/data/assets/scene/digitaluniverse/2mass.asset +++ b/data/assets/scene/digitaluniverse/2mass.asset @@ -43,6 +43,7 @@ local Object = { GUI = { Name = "2MASS Galaxies", Path = "/Universe/Nearby Surveys", + Focusable = false, Description = [[The Two Micron All-Sky Survey (2MASS) is an infrared survey of the sky published in 2003. Taken from two telescopes in Arizona and Chile, it offers an all-sky view of galaxies beyond the Milky Way. Because it is infrared, the light diff --git a/data/assets/scene/digitaluniverse/6dF.asset b/data/assets/scene/digitaluniverse/6dF.asset index 48039ecc6e..ae1cc7c4cd 100644 --- a/data/assets/scene/digitaluniverse/6dF.asset +++ b/data/assets/scene/digitaluniverse/6dF.asset @@ -42,7 +42,8 @@ local Object = { }, GUI = { Name = "6dF Galaxies", - Path = "/Universe/Deep Sky Surveys", + Path = "/Universe/Nearby Surveys", + Focusable = false, Description = [[The Six-degree Field (6dF) Galaxy Survey mapped nearly half the sky from the Anglo-Australian Observatory. Because it's a southern hemisphere survey, there is no coverage in these data for the northern hemisphere's sky. As with all diff --git a/data/assets/scene/digitaluniverse/abell.asset b/data/assets/scene/digitaluniverse/abell.asset index a7282aaac8..9c37cc52b7 100644 --- a/data/assets/scene/digitaluniverse/abell.asset +++ b/data/assets/scene/digitaluniverse/abell.asset @@ -51,6 +51,7 @@ local Object = { GUI = { Name = "Abell Galaxy Clusters", Path = "/Universe/Deep Sky Surveys", + Focusable = false, Description = [[The Abell catalog includes all the nearby, and not so nearby, galaxy clusters. The northern hemisphere survey, published in 1958, was compiled by George Abell from the Palomar Sky Survey plates. A subsequent southern hemisphere catalog diff --git a/data/assets/scene/digitaluniverse/allsky_hydrogenalpha.asset b/data/assets/scene/digitaluniverse/allsky_hydrogenalpha.asset index caf7cfde10..501e7b4876 100644 --- a/data/assets/scene/digitaluniverse/allsky_hydrogenalpha.asset +++ b/data/assets/scene/digitaluniverse/allsky_hydrogenalpha.asset @@ -23,11 +23,14 @@ local Object = { Texture = textures .. "mwHalpha-f.png", Orientation = "Inside", MirrorTexture = true, - FadeOutThreshold = 0.025 + FadeOutThreshold = 0.025, + BlendingOption = "Additive", + DisableDepth = true }, GUI = { - Name = "Hydrogen Alpha", + Name = "Hydrogen-alpha All-sky", Path = "/Milky Way/All Sky Images", + Focusable = false, Description = [[Hydrogen-alpha is a term that describes light from the ground state of the hydrogen atom. When an electron in an atom moves from one energy level to a higher one, we say the atom is excited. When the electron moves back down to the diff --git a/data/assets/scene/digitaluniverse/allsky_visible.asset b/data/assets/scene/digitaluniverse/allsky_visible.asset index 2a40c61c6e..f88c4344a7 100644 --- a/data/assets/scene/digitaluniverse/allsky_visible.asset +++ b/data/assets/scene/digitaluniverse/allsky_visible.asset @@ -29,8 +29,9 @@ local Object = { }, Tag = { "daytime_hidden" }, GUI = { - Name = "Visible Milky Way", + Name = "Visible All-sky", Path = "/Milky Way/All Sky Images", + Focusable = false, Description = [[An all-sky image of the night sky as our eye sees it (in the visible spectrum), with the stars removed. You will see the brightest part of the Galaxy if you look toward Galactic center toward the constellations Scorpius and Sagittarius. diff --git a/data/assets/scene/digitaluniverse/alternatestarlabels.asset b/data/assets/scene/digitaluniverse/alternatestarlabels.asset index 04e2dff18c..f0a371ac15 100644 --- a/data/assets/scene/digitaluniverse/alternatestarlabels.asset +++ b/data/assets/scene/digitaluniverse/alternatestarlabels.asset @@ -25,6 +25,7 @@ local Object = { GUI = { Name = "Stars Labels - Alternate", Path = "/Milky Way/Stars", + Focusable = false, Description = [[Alternate star labels for the stars. Priority goes to Bayer IDs (Greek designations, like Alpha Orionis), then to Flamsteed numbers (like 1 Orionis).]] diff --git a/data/assets/scene/digitaluniverse/backgroundradiation.asset b/data/assets/scene/digitaluniverse/backgroundradiation.asset index e1a753a756..c7997a51d0 100644 --- a/data/assets/scene/digitaluniverse/backgroundradiation.asset +++ b/data/assets/scene/digitaluniverse/backgroundradiation.asset @@ -30,10 +30,12 @@ local COBE = { Texture = textures .. "COBErect.png", Orientation = "Both", MirrorTexture = true, - FadeInThreshold = 0.4 + FadeInThreshold = 0.4, + BlendingOption = "Additive", + DisableDepth = true }, GUI = { - Name = "1990 COBE CMB", + Name = "COBE", Path = "/Universe/Cosmic Microwave Background", Description = [[In 1990, COBE, the Cosmic Background Explorer, took the first detailed map of the cosmic microwave background light. The red areas are @@ -62,10 +64,12 @@ local WMAP = { Texture = textures .. "wmap_ilc_7yr_v4_200uK_RGB_sos.png", Orientation = "Both", MirrorTexture = true, - FadeInThreshold = 0.4 + FadeInThreshold = 0.4, + BlendingOption = "Additive", + DisableDepth = true }, GUI = { - Name = "2003 WMAP CMB", + Name = "WMAP", Path = "/Universe/Cosmic Microwave Background", Description = [[WMAP, the Wilkinson Microwave Anisotropy Probe, released this all-sky image of the cosmic microwave background light in 2003. The blue colors are slightly @@ -93,10 +97,12 @@ local Planck = { Texture = textures .. "cmb4k.jpg", Orientation = "Both", MirrorTexture = true, - FadeInThreshold = 0.4 + FadeInThreshold = 0.4, + BlendingOption = "Additive", + DisableDepth = true }, GUI = { - Name = "2013 Planck CMB", + Name = "Planck", Path = "/Universe/Cosmic Microwave Background", Description = [[The Planck mission's 2013 image of the cosmic microwave background light release is the most detailed view of the CMB we have to date. The orange @@ -111,6 +117,11 @@ asset.onInitialize(function() openspace.addSceneGraphNode(COBE) openspace.addSceneGraphNode(WMAP) openspace.addSceneGraphNode(Planck) + + openspace.setGuiOrder( + "/Universe/Cosmic Microwave Background", + { COBE.Identifier, WMAP.Identifier, Planck.Identifier } + ) end) asset.onDeinitialize(function() diff --git a/data/assets/scene/digitaluniverse/backgroundradiation_multiverse.asset b/data/assets/scene/digitaluniverse/backgroundradiation_multiverse.asset index 7af1e3f312..82fd1809dd 100644 --- a/data/assets/scene/digitaluniverse/backgroundradiation_multiverse.asset +++ b/data/assets/scene/digitaluniverse/backgroundradiation_multiverse.asset @@ -27,7 +27,9 @@ local PlanckMultiverse1 = { Texture = textures .. "cmb4k.jpg", Orientation = "Both", MirrorTexture = true, - FadeInThreshold = 0.4 + FadeInThreshold = 0.4, + BlendingOption = "Additive", + DisableDepth = true }, GUI = { Name = "Planck Multiverse 1", @@ -56,7 +58,9 @@ local PlanckMultiverse2 = { Texture = textures .. "cmb4k.jpg", Orientation = "Both", MirrorTexture = true, - FadeInThreshold = 0.4 + FadeInThreshold = 0.4, + BlendingOption = "Additive", + DisableDepth = true }, GUI = { Name = "Planck Multiverse 2", @@ -85,7 +89,9 @@ local PlanckMultiverse3 = { Texture = textures .. "cmb4k.jpg", Orientation = "Both", MirrorTexture = true, - FadeInThreshold = 0.4 + FadeInThreshold = 0.4, + BlendingOption = "Additive", + DisableDepth = true }, GUI = { Name = "Planck Multiverse 3", @@ -114,7 +120,9 @@ local PlanckMultiverse4 = { Texture = textures .. "cmb4k.jpg", Orientation = "Both", MirrorTexture = true, - FadeInThreshold = 0.4 + FadeInThreshold = 0.4, + BlendingOption = "Additive", + DisableDepth = true }, GUI = { Name = "Planck Multiverse 4", diff --git a/data/assets/scene/digitaluniverse/brown_dwarfs.asset b/data/assets/scene/digitaluniverse/brown_dwarfs.asset index 768a4791d6..5970cc5c25 100644 --- a/data/assets/scene/digitaluniverse/brown_dwarfs.asset +++ b/data/assets/scene/digitaluniverse/brown_dwarfs.asset @@ -9,7 +9,7 @@ local speck = asset.resource({ Name = "Brown Dwarf Speck Files", Type = "HttpSynchronization", Identifier = "digitaluniverse_brown_dwarfs_speck", - Version = 1 + Version = 2 }) @@ -36,11 +36,19 @@ local Object = { ScaleExponent = 15.8, MaxSize = 0.7, EnableMaxSizeControl = true + }, + Labels = { + File = speck .. "bd.label", + Color = { 0.6, 0.3, 0.4 }, + Size = 13.75, + MinMaxSize = { 4, 30 }, + Unit = "pc" } }, GUI = { Name = "Brown Dwarfs", Path = "/Milky Way/Substellar Objects", + Focusable = false, Description = [[For decades it was believed that M stars were the coolest stars in the Galaxy. Some M stars, called red dwarfs, make up 70% of the stars in the Galaxy. However, a new class of objects, even cooler than M stars, was recently @@ -72,7 +80,7 @@ asset.export(Object) asset.meta = { Name = "Brown Dwarfs", - Author = "Brian Abbott, Zack Reeves, Jackie Faherty (AMNH)", + Author = "Brian Abbott, Zack Reeves, Ally Baldelli, Jackie Faherty (AMNH)", Description = Object.GUI.Description, License = "AMNH Digital Universe", URL = "https://www.amnh.org/research/hayden-planetarium/digital-universe", diff --git a/data/assets/scene/digitaluniverse/constellationbounds.asset b/data/assets/scene/digitaluniverse/constellationbounds.asset index b366279854..af3fe956ac 100644 --- a/data/assets/scene/digitaluniverse/constellationbounds.asset +++ b/data/assets/scene/digitaluniverse/constellationbounds.asset @@ -21,6 +21,7 @@ local Object = { Enabled = false, File = data .. "bound_20.dat", NamesFile = data .. "constellations.dat", + Color = { 0.45, 0.44, 0.30 } -- Selection = zodiacs }, Transform = { @@ -34,9 +35,11 @@ local Object = { Scale = 10e17 } }, + Tag = { "du_grid" }, GUI = { Name = "Constellation Boundaries", Path = "/Milky Way/Constellations", + Focusable = false, Description = [[As a continent is divided into countries, astronomers divide the sky into 88 regions called constellations. Every object falls into one of these 88 regions. The boundaries of these regions are shown in this asset. Use these in diff --git a/data/assets/scene/digitaluniverse/constellations.asset b/data/assets/scene/digitaluniverse/constellations.asset index bf1957ef16..5aaa5f1208 100644 --- a/data/assets/scene/digitaluniverse/constellations.asset +++ b/data/assets/scene/digitaluniverse/constellations.asset @@ -56,6 +56,7 @@ local Constellations = { GUI = { Name = "Constellation Lines", Path = "/Milky Way/Constellations", + Focusable = false, Description = [[Lines connecting the stars that make up the constellation figures. We represent the constellations by connecting the main stars that make up the constellation "stick figures," as seen from Earth. Colors: most constellations diff --git a/data/assets/scene/digitaluniverse/deepsky.asset b/data/assets/scene/digitaluniverse/deepsky.asset index 3973a79262..9661feb681 100644 --- a/data/assets/scene/digitaluniverse/deepsky.asset +++ b/data/assets/scene/digitaluniverse/deepsky.asset @@ -15,6 +15,12 @@ local speck = asset.resource({ local DeepSkyObjects = { Identifier = "DeepSkyObjects", + Transform = { + Rotation = { + Type = "StaticRotation", + Rotation = { 0, 0, math.pi } + } + }, Renderable = { Type = "RenderablePointCloud", Enabled = false, @@ -41,21 +47,22 @@ local DeepSkyObjects = { EnableMaxSizeControl = true } }, - Transform = { - Rotation = { - Type = "StaticRotation", - Rotation = { 0, 0, math.pi } - } - }, GUI = { Name = "Deep Sky Objects Points", Path = "/Universe/Nearby Surveys", + Focusable = false, Description = "Point cloud and labels for Deep Sky Objects" } } local DeepSkyObjectsImages = { Identifier = "DeepSkyObjectsImages", + Transform = { + Rotation = { + Type = "StaticRotation", + Rotation = { math.pi, math.pi, 0 } + } + }, Renderable = { Type = "RenderablePointCloud", Enabled = false, @@ -66,7 +73,7 @@ local DeepSkyObjectsImages = { }, -- Use fixed orientation, and rotate planes based on orientation information in -- the dataset - OrientationRenderOption = "Fixed Rotation", + Billboard = "Fixed Rotation", UseOrientationData = true, Unit = "pc", SizeSettings = { @@ -79,15 +86,10 @@ local DeepSkyObjectsImages = { ScaleExponent = 0.0 } }, - Transform = { - Rotation = { - Type = "StaticRotation", - Rotation = { math.pi, math.pi, 0 } - } - }, GUI = { Name = "Deep Sky Objects Images", Path = "/Universe/Nearby Surveys", + Focusable = false, Description = [[Census: 63 images and labels. DU Version 1.3.
These data are 2-D images of Messier objects placed in 3-D space. Not only do we place these images at the proper location and give them the correct orientation, we also diff --git a/data/assets/scene/digitaluniverse/digitaluniverse.asset b/data/assets/scene/digitaluniverse/digitaluniverse.asset index 36ff48a180..a65761b468 100644 --- a/data/assets/scene/digitaluniverse/digitaluniverse.asset +++ b/data/assets/scene/digitaluniverse/digitaluniverse.asset @@ -1,10 +1,15 @@ +-- The only reason the SDSS asset is loaded at the top of this list is to start the +-- loading as soon as possible, as this asset is the most time intensive to initialize and +-- we want to minimize the waiting time on startup asset.require("./sdss") + asset.require("./2dF") asset.require("./2mass") asset.require("./6dF") asset.require("./abell") asset.require("./allsky_hydrogenalpha") asset.require("./allsky_visible") +asset.require("./alternatestarlabels") asset.require("./backgroundradiation") asset.require("./backgroundradiation_multiverse") asset.require("./brown_dwarfs") @@ -28,7 +33,6 @@ asset.require("./planetarynebulae") asset.require("./pulsars") asset.require("./quasars") asset.require("./starlabels") -asset.require("./alternatestarlabels") asset.require("./starorbits") asset.require("./star_uncertainty") asset.require("./stars") diff --git a/data/assets/scene/digitaluniverse/exoplanets.asset b/data/assets/scene/digitaluniverse/exoplanets.asset index ec0dcdfdf7..8892a640ec 100644 --- a/data/assets/scene/digitaluniverse/exoplanets.asset +++ b/data/assets/scene/digitaluniverse/exoplanets.asset @@ -9,7 +9,7 @@ local speck = asset.resource({ Name = "Exoplanets Speck Files", Type = "HttpSynchronization", Identifier = "digitaluniverse_exoplanets_speck", - Version = 4 + Version = 5 }) @@ -38,8 +38,9 @@ local Object = { } }, GUI = { - Name = "Exoplanets", + Name = "Exoplanet Systems", Path = "/Milky Way/Exoplanets", + Focusable = false, Description = [[Extrasolar planets, or exoplanets, are a relatively new phenomenon in astronomy - no observational evidence was available until 1995. To the eye, exoplanets are lost in the glare of their host star. Unconventional techniques are @@ -67,7 +68,7 @@ asset.export(Object) asset.meta = { Name = "Exoplanets", Description = Object.GUI.Description, - Author = "Brian Abbott, Zack Reeves (AMNH)", + Author = "Brian Abbott, Zack Reeves, Ally Baldelli (AMNH)", URL = "https://www.amnh.org/research/hayden-planetarium/digital-universe", License = "AMNH Digital Universe" } diff --git a/data/assets/scene/digitaluniverse/exoplanets_candidates.asset b/data/assets/scene/digitaluniverse/exoplanets_candidates.asset index 91d8dcaba8..937f742521 100644 --- a/data/assets/scene/digitaluniverse/exoplanets_candidates.asset +++ b/data/assets/scene/digitaluniverse/exoplanets_candidates.asset @@ -9,7 +9,7 @@ local speck = asset.resource({ Name = "Exoplanets Candidates Speck Files", Type = "HttpSynchronization", Identifier = "digitaluniverse_exoplanets_candidates_speck", - Version = 2 + Version = 3 }) @@ -40,8 +40,9 @@ local Object = { } }, GUI = { - Name = "Exoplanetary Candidates", + Name = "Exoplanet Candidates", Path = "/Milky Way/Exoplanets", + Focusable = false, Description = [[The exoplanet candidate stars are likely hosts for exoplanets. These are stars plucked from NASA's Kepler and TESS space telescopes. Further observations are needed to confirm a planet's existence. Rather than represent them @@ -69,7 +70,7 @@ asset.export(Object) asset.meta = { Name = "Exoplanetary Candidates", Description = Object.GUI.Description, - Author = "Brian Abbott, Zack Reeves, Emily Rice, and Jason No (AMNH)", + Author = "Brian Abbott, Ally Baldelli, Zack Reeves, Emily Rice, and Jason No (AMNH)", URL = "https://www.amnh.org/research/hayden-planetarium/digital-universe", License = "AMNH Digital Universe" } diff --git a/data/assets/scene/digitaluniverse/galaxy_clusters.asset b/data/assets/scene/digitaluniverse/galaxy_clusters.asset index bd7fda1509..4fa281e82d 100644 --- a/data/assets/scene/digitaluniverse/galaxy_clusters.asset +++ b/data/assets/scene/digitaluniverse/galaxy_clusters.asset @@ -31,6 +31,7 @@ local Object = { GUI = { Name = "Galaxy Cluster Labels", Path = "/Universe/Nearby Surveys", + Focusable = false, Description = [[The galaxy clusters dataset is a series of labels that mark where the large clusters of galaxies are in the nearby universe. These labels must be used in conjunction with the Tully galaxy group. Census: 15 galaxy cluster labels.]] diff --git a/data/assets/scene/digitaluniverse/galaxy_groups.asset b/data/assets/scene/digitaluniverse/galaxy_groups.asset index e051227eee..17046d9f6b 100644 --- a/data/assets/scene/digitaluniverse/galaxy_groups.asset +++ b/data/assets/scene/digitaluniverse/galaxy_groups.asset @@ -31,6 +31,7 @@ local Object = { GUI = { Name = "Galaxy Group Labels", Path = "/Universe/Nearby Surveys", + Focusable = false, Description = [[The Galaxy Groups data are a set of labels that mark the nearby galaxy groups. The Milky Way is in the Local Group, and we are surrounded by many other groups delineated by these labels. Census: 62 galaxy group labels.]] diff --git a/data/assets/scene/digitaluniverse/globularclusters.asset b/data/assets/scene/digitaluniverse/globularclusters.asset index c2f97e6a63..39e970e411 100644 --- a/data/assets/scene/digitaluniverse/globularclusters.asset +++ b/data/assets/scene/digitaluniverse/globularclusters.asset @@ -41,6 +41,7 @@ local Object = { GUI = { Name = "Globular Clusters", Path = "/Milky Way/Star Clusters", + Focusable = false, Description = [[Globular star clusters are gravitationally bound groups of 100,000 to 1 million stars. They are compact, spherical "balls" of stars with very high stellar densities. These clusters are typically 30 to 100 light years in diameter. diff --git a/data/assets/scene/digitaluniverse/grids.asset b/data/assets/scene/digitaluniverse/grids.asset index d36526ba0d..78db5edd2d 100644 --- a/data/assets/scene/digitaluniverse/grids.asset +++ b/data/assets/scene/digitaluniverse/grids.asset @@ -64,9 +64,11 @@ local RadioSphere = { Color = { 0.3, 0.84, 1.0 }, LineWidth = 2.0 }, + Tag = { "du_grid" }, GUI = { Name = "Radio Sphere", Path = "/Milky Way/Grids", + Focusable = false, Description = [[The radio sphere describes the theoretical extent of Earth's radio signals in space. Before television carrier waves, early-warning radar first used in World War II, and the detonation of atomic weapons, Earth was radio-quiet to the @@ -102,11 +104,14 @@ local EquatorialSphere = { Opacity = 1.0, Color = { 0.3, 0.3, 0.15 }, LineWidth = 2.0, - GridSegments = { 18, 24 }, + LatSegments = 36, + LongSegments = 24, }, + Tag = { "du_grid" }, GUI = { Name = "Equatorial Coordinates", Path = "/Night Sky/Coordinate Systems/Equatorial", + Focusable = false, Description = [[An 80-light-year sphere representing equatorial coordinates (right ascension and declination).]] } @@ -131,9 +136,11 @@ local EquatorialSphereLabels = { Unit = "pc", TransformationMatrix = EquatorialTransformationMatrix }, + Tag = { "du_grid_labels" }, GUI = { Name = "Equatorial Coordinates Labels", Path = "/Night Sky/Coordinate Systems/Equatorial", + Focusable = false, Description = [[Labels on a sphere representing right ascension in hours and declination in degrees.]] } @@ -159,9 +166,11 @@ local EclipticSphere = { Color = { 0.3, 0.15, 0.15 }, LineWidth = 2.0 }, + Tag = { "du_grid" }, GUI = { Name = "Ecliptic Coordinates", Path = "/Night Sky/Coordinate Systems/Ecliptic", + Focusable = false, Description = [[A 100-light-year sphere representing ecliptic coordinates (ecliptic longitude and latitude).]] } @@ -186,9 +195,11 @@ local EclipticSphereLabels = { Unit = "pc", TransformationMatrix = EclipticTransformationMatrix }, + Tag = { "du_grid_labels" }, GUI = { Name = "Ecliptic Coordinates Labels", Path = "/Night Sky/Coordinate Systems/Ecliptic", + Focusable = false, Description = [[Labels on a sphere representing ecliptic longitude and latitude in degrees.]] } @@ -210,9 +221,11 @@ local GalacticSphere = { Opacity = 1.0, Color = { 0.05, 0.25, 0.25 } }, + Tag = { "du_grid" }, GUI = { Name = "Galactic Coordinates", Path = "/Night Sky/Coordinate Systems/Galactic", + Focusable = false, Description = [[A 1000-light-year sphere representing galactic coordinates (galactic longitude and latitude).]] } @@ -235,9 +248,11 @@ local GalacticSphereLabels = { Opacity = 0.65, Unit = "pc" }, + Tag = { "du_grid_labels" }, GUI = { Name = "Galactic Coordinates Labels", Path = "/Night Sky/Coordinate Systems/Galactic", + Focusable = false, Description = [[Labels on a sphere representing galactic longitude and latitude in degrees.]] } @@ -268,10 +283,13 @@ local Plane1lh = { Segments = { 20, 20 }, Size = { 2 * LightHour, 2 * LightHour } }, + Tag = { "du_grid" }, GUI = { Name = "1-light-hour Grid", Path = "/Solar System/Grids", - Description = [[A 1-light-hour Cartesian grid aligned on the plane of the Solar System.]], + Focusable = false, + Description = [[A 1-light-hour Cartesian grid aligned on the plane of the Solar + System.]], OrderingNumber = LightHour } } @@ -301,10 +319,13 @@ local Plane1ld = { Segments = { 20, 20 }, Size = { 2 * LightDay, 2 * LightDay } }, + Tag = { "du_grid" }, GUI = { Name = "1-light-day Grid", Path = "/Solar System/Grids", - Description = [[A 1-light-day Cartesian grid aligned on the plane of the Solar System.]], + Focusable = false, + Description = [[A 1-light-day Cartesian grid aligned on the plane of the Solar + System.]], OrderingNumber = LightDay } } @@ -334,10 +355,13 @@ local Plane1lm = { Segments = { 20, 20 }, Size = { 2 * LightMonth, 2 * LightMonth } }, + Tag = { "du_grid" }, GUI = { Name = "1-light-month Grid", Path = "/Solar System/Grids", - Description = [[A 1-light-month Cartesian grid aligned on the plane of the Solar System.]], + Focusable = false, + Description = [[A 1-light-month Cartesian grid aligned on the plane of the Solar + System.]], OrderingNumber = LightMonth } } @@ -367,10 +391,13 @@ local Plane1ly = { Segments = { 20, 20 }, Size = { 2 * LightYear, 2 * LightYear } }, + Tag = { "du_grid" }, GUI = { Name = "1-light-year Grid", Path = "/Solar System/Grids", - Description = [[A 1-light-year Cartesian grid aligned on the plane of the Solar System.]], + Focusable = false, + Description = [[A 1-light-year Cartesian grid aligned on the plane of the Solar + System.]], OrderingNumber = LightYear } } @@ -400,10 +427,13 @@ local Plane10ly = { Segments = { 20, 20 }, Size = { 10 * 2 * LightYear, 10 * 2 * LightYear } }, + Tag = { "du_grid" }, GUI = { Name = "10-light-year Grid", Path = "/Milky Way/Grids", - Description = [[A 10-light-year Cartesian grid aligned on the plane of the Solar System.]], + Focusable = false, + Description = [[A 10-light-year Cartesian grid aligned on the plane of the Solar + System.]], OrderingNumber = 10 * LightYear } } @@ -433,10 +463,13 @@ local Plane100ly = { Segments = { 20, 20 }, Size = { 100 * 2 * LightYear, 100 * 2 * LightYear } }, + Tag = { "du_grid" }, GUI = { Name = "100-light-year Grid", Path = "/Milky Way/Grids", - Description = [[A 100-light-year Cartesian grid aligned on the plane of the Solar System.]], + Focusable = false, + Description = [[A 100-light-year Cartesian grid aligned on the plane of the Solar + System.]], OrderingNumber = 100 * LightYear } } @@ -466,10 +499,13 @@ local Plane1kly = { Segments = { 20, 20 }, Size = { 1000 * 2 * LightYear, 1000 * 2 * LightYear } }, + Tag = { "du_grid" }, GUI = { Name = "1,000-light-year Grid", Path = "/Milky Way/Grids", - Description = [[A 1,000-light-year Cartesian grid aligned on the plane of the Solar System.]], + Focusable = false, + Description = [[A 1,000-light-year Cartesian grid aligned on the plane of the Solar + System.]], OrderingNumber = 1000 * LightYear } } @@ -499,10 +535,13 @@ local Plane10kly = { Segments = { 20, 20 }, Size = { 10000 * 2 * LightYear, 10000 * 2 * LightYear } }, + Tag = { "du_grid" }, GUI = { Name = "10,000-light-year Grid", Path = "/Milky Way/Grids", - Description = [[A 10,000-light-year Cartesian grid aligned on the plane of the Solar System.]], + Focusable = false, + Description = [[A 10,000-light-year Cartesian grid aligned on the plane of the Solar + System.]], OrderingNumber = 10000 * LightYear } } @@ -527,10 +566,13 @@ local Plane100kly = { HighlightRate = { 5, 5 }, Size = { 100000 * 2 * LightYear, 100000 * 2 * LightYear } }, + Tag = { "du_grid" }, GUI = { Name = "100,000-light-year Grid", Path = "/Universe/Grids", - Description = [[A 100,000-light-year Cartesian grid aligned on the plane of the Milky Way.]], + Focusable = false, + Description = [[A 100,000-light-year Cartesian grid aligned on the plane of the Milky + Way.]], OrderingNumber = 100000 * LightYear } } @@ -555,10 +597,13 @@ local Plane1Mly = { HighlightRate = { 5, 5 }, Size = { 1E6 * 2 * LightYear, 1E6 * 2 * LightYear } }, + Tag = { "du_grid" }, GUI = { Name = "1-million-light-year Grid", Path = "/Universe/Grids", - Description = [[A 1-million-light-year Cartesian grid aligned on the plane of the Milky Way.]], + Focusable = false, + Description = [[A 1-million-light-year Cartesian grid aligned on the plane of the + Milky Way.]], OrderingNumber = 1E6 * LightYear } } @@ -583,10 +628,13 @@ local Plane10Mly = { HighlightRate = { 5, 5 }, Size = { 10E6 * 2 * LightYear, 10E6 * 2 * LightYear } }, + Tag = { "du_grid" }, GUI = { Name = "10-million-light-year Grid", Path = "/Universe/Grids", - Description = [[A 10-million-light-year Cartesian grid aligned on the plane of the Milky Way.]], + Focusable = false, + Description = [[A 10-million-light-year Cartesian grid aligned on the plane of the + Milky Way.]], OrderingNumber = 10E6 * LightYear } } @@ -611,10 +659,13 @@ local Plane100Mly = { HighlightRate = { 5, 5 }, Size = { 100E6 * 2 * LightYear, 100E6 * 2 * LightYear } }, + Tag = { "du_grid" }, GUI = { Name = "100-million-light-year Grid", Path = "/Universe/Grids", - Description = [[A 100-million-light-year Cartesian grid aligned on the plane of the Milky Way.]], + Focusable = false, + Description = [[A 100-million-light-year Cartesian grid aligned on the plane of the + Milky Way.]], OrderingNumber = 100E6 * LightYear } } @@ -639,10 +690,13 @@ local Plane20Gly = { HighlightRate = { 5, 5 }, Size = { 20E9 * 2 * LightYear, 20E9 * 2 * LightYear } }, + Tag = { "du_grid" }, GUI = { Name = "20-billion-light-year Grid", Path = "/Universe/Grids", - Description = [[A 20-billion-light-year Cartesian grid aligned on the plane of the Milky Way.]], + Focusable = false, + Description = [[A 20-billion-light-year Cartesian grid aligned on the plane of the + Milky Way.]], OrderingNumber = 20E9 * LightYear } } diff --git a/data/assets/scene/digitaluniverse/h2regions.asset b/data/assets/scene/digitaluniverse/h2regions.asset index 21f88f9a7f..bfecc087a4 100644 --- a/data/assets/scene/digitaluniverse/h2regions.asset +++ b/data/assets/scene/digitaluniverse/h2regions.asset @@ -41,6 +41,7 @@ local Object = { GUI = { Name = "HII Regions", Path = "/Milky Way/Nebulae", + Focusable = false, Description = [[HII (pronounced "H-two") regions are stellar nurseries for newborn stars. Stars are born from condensing clouds of hydrogen gas. As these clouds condense, the densities become high enough to form stars. An HII region is the diff --git a/data/assets/scene/digitaluniverse/hdf.asset b/data/assets/scene/digitaluniverse/hdf.asset index 68585a4aa7..ba2921785b 100644 --- a/data/assets/scene/digitaluniverse/hdf.asset +++ b/data/assets/scene/digitaluniverse/hdf.asset @@ -43,6 +43,7 @@ local Object = { GUI = { Name = "Hubble Deep Field", Path = "/Universe/Galaxies", + Focusable = false, Description = [[ Hubble Ultra Deep Field galaxy survey

Data Reference: Hubble Ultra Deep Field 2012 program (Ellis+, Koekemoer+, 2013) diff --git a/data/assets/scene/digitaluniverse/local_group_dwarfs.asset b/data/assets/scene/digitaluniverse/local_group_dwarfs.asset index 4535910ce0..df4b8ccd05 100644 --- a/data/assets/scene/digitaluniverse/local_group_dwarfs.asset +++ b/data/assets/scene/digitaluniverse/local_group_dwarfs.asset @@ -32,7 +32,7 @@ local Object = { ColorMapping = { File = speck .. "localgroup.cmap", ParameterOptions = { - { Key = "association" } + { Key = "association", Range = { 0, 4 } } } } }, @@ -47,6 +47,7 @@ local Object = { GUI = { Name = "Local Group", Path = "/Universe/Nearby Surveys", + Focusable = false, Description = [[A group of galaxies is typically composed of a small number of large galaxies that are surrounded by a large number of small galaxies. The Milky Way belongs to the Local Group, and is one of roughly 100 galaxies in that group. The diff --git a/data/assets/scene/digitaluniverse/milkyway.asset b/data/assets/scene/digitaluniverse/milkyway.asset index dd9cf291d0..b8c8daf176 100644 --- a/data/assets/scene/digitaluniverse/milkyway.asset +++ b/data/assets/scene/digitaluniverse/milkyway.asset @@ -24,7 +24,7 @@ local Object = { }, -- Use fixed orientation, and rotate planes based on orientation information in -- the dataset - OrientationRenderOption = "Fixed Rotation", + Billboard = "Fixed Rotation", UseOrientationData = true, Unit = "pc", Fading = { @@ -38,8 +38,9 @@ local Object = { }, }, GUI = { - Name = "Milky Way Galaxy Image", + Name = "Milky Way Image", Path = "/Milky Way/Galaxy", + Focusable = false, Description = [[The exterior view of the Milky Way is represented here by a two-dimensional image. The image is that of NGC 1232, a galaxy thought to resemble our Milky Way. The image has been properly sized and approximately oriented to diff --git a/data/assets/scene/digitaluniverse/milkyway_arm_labels.asset b/data/assets/scene/digitaluniverse/milkyway_arm_labels.asset index 10e31e117c..2474e6a1f0 100644 --- a/data/assets/scene/digitaluniverse/milkyway_arm_labels.asset +++ b/data/assets/scene/digitaluniverse/milkyway_arm_labels.asset @@ -25,7 +25,7 @@ local Object = { }, -- Use fixed orientation, and rotate planes based on orientation information in -- the dataset - OrientationRenderOption = "Fixed Rotation", + Billboard = "Fixed Rotation", UseOrientationData = true, Unit = "pc", Fading = { @@ -39,8 +39,9 @@ local Object = { }, }, GUI = { - Name = "Milky Way Arms Labels", + Name = "Milky Way Arm Labels", Path = "/Milky Way/Galaxy", + Focusable = false, Description = [[This is an image that contains labels for the Milky Way's spiral arms. We label them in this manner--"hard-coding" the labels into an image rather than having native labels--so that they can retain their size, shape, and location diff --git a/data/assets/scene/digitaluniverse/milkyway_label.asset b/data/assets/scene/digitaluniverse/milkyway_label.asset index 5393556afc..6a198fd6ce 100644 --- a/data/assets/scene/digitaluniverse/milkyway_label.asset +++ b/data/assets/scene/digitaluniverse/milkyway_label.asset @@ -28,8 +28,9 @@ local Object = { GUI = { Name = "Home Label", Path = "/Universe/Nearby Surveys", - Description = [[Label for the Milky Way titled 'Home', sized for viewing outside - the Milky Way Galaxy.]] + Focusable = false, + Description = [[Label for the Milky Way titled 'Home', sized for viewing outside the + Milky Way Galaxy.]] } } diff --git a/data/assets/scene/digitaluniverse/obassociations.asset b/data/assets/scene/digitaluniverse/obassociations.asset index ad3a01a619..05df72c9c8 100644 --- a/data/assets/scene/digitaluniverse/obassociations.asset +++ b/data/assets/scene/digitaluniverse/obassociations.asset @@ -49,6 +49,7 @@ local Object = { GUI = { Name = "OB Associations", Path = "/Milky Way/Star Clusters", + Focusable = false, Description = [[Stellar associations are loose agglomerations of stars that form from the same gas cloud. OB associations typically have on the order of dozens of O and B stars in them (hotter, massive, younger stars) in addition to cooler stars. Over diff --git a/data/assets/scene/digitaluniverse/oort_cloud.asset b/data/assets/scene/digitaluniverse/oort_cloud.asset index 52c9e45384..2d3268fa0c 100644 --- a/data/assets/scene/digitaluniverse/oort_cloud.asset +++ b/data/assets/scene/digitaluniverse/oort_cloud.asset @@ -39,7 +39,8 @@ local Object = { }, GUI = { Name = "Oort Sphere", - Path = "/Solar System/Comets", + Path = "/Solar System/Comets/Oort Cloud", + Focusable = false, Description = [[The Oort cloud is a region of space surrounding the Sun where comets are believed to originate. It is believed to extend from 20,000-100,000 Astronomical Units (AU), with its greatest concentration around 50,000 AU (1 AU is the average diff --git a/data/assets/scene/digitaluniverse/openclusters.asset b/data/assets/scene/digitaluniverse/openclusters.asset index 035b42cda3..045da77825 100644 --- a/data/assets/scene/digitaluniverse/openclusters.asset +++ b/data/assets/scene/digitaluniverse/openclusters.asset @@ -41,12 +41,13 @@ local Object = { GUI = { Name = "Open Star Clusters", Path = "/Milky Way/Star Clusters", + Focusable = false, Description = [[An open star cluster is a loose assemblage of stars numbering from hundreds to thousands that are bound by their mutual gravitation. Because these are young stars, we expect to see them in the star-forming regions of our Galaxy, namely in the spiral arms. For this reason, open clusters exist, for the most part, in the - plane of the Galaxy and indicate relatively recent star formation. Census: 1,867 star - clusters.]] + plane of the Galaxy and indicate relatively recent star formation. Census: 1,867 + star clusters.]] } } diff --git a/data/assets/scene/digitaluniverse/planetarynebulae.asset b/data/assets/scene/digitaluniverse/planetarynebulae.asset index 68ce205538..9e6ee8f5ff 100644 --- a/data/assets/scene/digitaluniverse/planetarynebulae.asset +++ b/data/assets/scene/digitaluniverse/planetarynebulae.asset @@ -41,6 +41,7 @@ local Object = { GUI = { Name = "Planetary Nebulae", Path = "/Milky Way/Nebulae", + Focusable = false, Description = [[A planetary nebula is an expanding shell of gas ejected from an average-sized star late in its life cycle. Appearing like greenish disks to a telescopic observer, planetary nebulae received their name from their resemblance to diff --git a/data/assets/scene/digitaluniverse/pulsars.asset b/data/assets/scene/digitaluniverse/pulsars.asset index 82be71fa9b..0459a2aa76 100644 --- a/data/assets/scene/digitaluniverse/pulsars.asset +++ b/data/assets/scene/digitaluniverse/pulsars.asset @@ -41,6 +41,7 @@ local Object = { GUI = { Name = "Pulsars", Path = "/Milky Way/Stellar Remnants", + Focusable = false, Description = [[A pulsar is a spinning neutron star, an ultra-dense stellar remnant resulting from a supernova-driven collapse of the stellar core. Upon death, stars leave behind one of three possible remnants: a white dwarf, a neutron star, or a diff --git a/data/assets/scene/digitaluniverse/quasars.asset b/data/assets/scene/digitaluniverse/quasars.asset index d9482df27a..17f60fbe15 100644 --- a/data/assets/scene/digitaluniverse/quasars.asset +++ b/data/assets/scene/digitaluniverse/quasars.asset @@ -53,6 +53,7 @@ local Object = { GUI = { Name = "Quasars", Path = "/Universe/Deep Sky Surveys", + Focusable = false, Description = [[Quasars are the most distant objects we see. They are extremely active galaxies that contain supermassive black holes which gobble up material at a furious rate. As the material falls into the black hole, it forms a disk and emits diff --git a/data/assets/scene/digitaluniverse/sdss.asset b/data/assets/scene/digitaluniverse/sdss.asset index 7d59a9d162..01516a3450 100644 --- a/data/assets/scene/digitaluniverse/sdss.asset +++ b/data/assets/scene/digitaluniverse/sdss.asset @@ -43,8 +43,9 @@ local Object = { } }, GUI = { - Name = "Sloan Digital Sky Survey", + Name = "Sloan Galaxies", Path = "/Universe/Deep Sky Surveys", + Focusable = false, Description = [[The Sloan Digital Sky Survey (SDSS) is an ambitious project to image about 35% of the sky, deep into the universe. The SDSS galaxies form triangular wedges, revealing those parts of the sky observed by the telescope. If the entire diff --git a/data/assets/scene/digitaluniverse/star_uncertainty.asset b/data/assets/scene/digitaluniverse/star_uncertainty.asset index 2273022321..4cce63a172 100644 --- a/data/assets/scene/digitaluniverse/star_uncertainty.asset +++ b/data/assets/scene/digitaluniverse/star_uncertainty.asset @@ -31,6 +31,7 @@ local Object = { GUI = { Name = "Star Distance Uncertainty", Path = "/Milky Way/Stars", + Focusable = false, Description = [[The uncertainty of a star's position is derived from the uncertainty in its parallax measurement. This results in a range in distance where the star could exist. Here we draw lines on top of select stars which give us a visual cue diff --git a/data/assets/scene/digitaluniverse/starlabels.asset b/data/assets/scene/digitaluniverse/starlabels.asset index 368ec4a330..21f951c5c5 100644 --- a/data/assets/scene/digitaluniverse/starlabels.asset +++ b/data/assets/scene/digitaluniverse/starlabels.asset @@ -25,6 +25,7 @@ local Object = { GUI = { Name = "Stars Labels", Path = "/Milky Way/Stars", + Focusable = false, Description = [[Common name labels for nearby stars in the Milky Way. See 'Stars' for more information.]] } diff --git a/data/assets/scene/digitaluniverse/starorbits.asset b/data/assets/scene/digitaluniverse/starorbits.asset index 4efbe36beb..283e5e5aff 100644 --- a/data/assets/scene/digitaluniverse/starorbits.asset +++ b/data/assets/scene/digitaluniverse/starorbits.asset @@ -24,6 +24,7 @@ local SunOrbit = { GUI = { Name = "Sun Orbit", Path = "/Milky Way/Stars/Stars Orbits", + Focusable = false, Description = [[Projected orbit of the Sun around the Milky Way over the next 1 billion years.]] } @@ -42,6 +43,7 @@ local BarnardsOrbit = { GUI = { Name = "Barnards Orbit", Path = "/Milky Way/Stars/Stars Orbits", + Focusable = false, Description = [[Projected orbit of Barnard's Star around the Milky Way over the next 1 billion years.]] } @@ -60,6 +62,7 @@ local KapteynsOrbit = { GUI = { Name = "Kapteyns Orbit", Path = "/Milky Way/Stars/Stars Orbits", + Focusable = false, Description = [[Projected orbit of Kapteyn's Star around the Milky Way over the next 1 billion years.]] } @@ -78,6 +81,7 @@ local Lacaille9352Orbit = { GUI = { Name = "Lacaille 9352 Orbit", Path = "/Milky Way/Stars/Stars Orbits", + Focusable = false, Description = [[Projected orbit of Lacaille9352 around the Milky Way over the next 1 billion years.]] } @@ -96,6 +100,7 @@ local LSR1826Orbit = { GUI = { Name = "LSR1826+3014 Orbit", Path = "/Milky Way/Stars/Stars Orbits", + Focusable = false, Description = [[Projected orbit of LSR1826+3014 around the Milky Way over the next 1 billion years.]] } @@ -114,6 +119,7 @@ local LSRJ0822Orbit = { GUI = { Name = "LSRJ0822+1700 Orbit", Path = "/Milky Way/Stars/Stars Orbits", + Focusable = false, Description = [[Projected orbit of LSRJ0822+1700 around the Milky Way over the next 1 billion years.]] } @@ -132,6 +138,7 @@ local PM_J13420Orbit = { GUI = { Name = "PM_J13420-3415 Orbit", Path = "/Milky Way/Stars/Stars Orbits", + Focusable = false, Description = [[Projected orbit of PM_J13420-3415 around the Milky Way over the next 1 billion years.]] } diff --git a/data/assets/scene/digitaluniverse/stars.asset b/data/assets/scene/digitaluniverse/stars.asset index ef29bce444..9534074eff 100644 --- a/data/assets/scene/digitaluniverse/stars.asset +++ b/data/assets/scene/digitaluniverse/stars.asset @@ -62,6 +62,7 @@ local Stars = { GUI = { Name = "Stars", Path = "/Milky Way/Stars", + Focusable = false, Description = [[These are the nearby stars that surround the Sun and are close enough to get accurate distances. These include all the stars we see with the unaided eye and many stars dimmer than that. Over the entire night sky, all year round, and in @@ -107,6 +108,7 @@ local SunStar = { GUI = { Name = "Sun", Path = "/Milky Way/Stars", + Focusable = false, Description = [[Individual star to represent the Sun when outside of the Solar System.]] } diff --git a/data/assets/scene/digitaluniverse/superclusters.asset b/data/assets/scene/digitaluniverse/superclusters.asset index 71c50f95ad..7f720a4a8c 100644 --- a/data/assets/scene/digitaluniverse/superclusters.asset +++ b/data/assets/scene/digitaluniverse/superclusters.asset @@ -42,6 +42,7 @@ local Object = { GUI = { Name = "Supercluster Labels", Path = "/Universe/Deep Sky Surveys", + Focusable = false, Description = [[The superclusters dataset is a set of labels that mark the major galaxy superclusters in the local universe. They correspond to, and should be viewed with, the Abell clusters. Astronomers estimate there are 10 million superclusters in diff --git a/data/assets/scene/digitaluniverse/supernovaremnants.asset b/data/assets/scene/digitaluniverse/supernovaremnants.asset index 3b890d0858..ae552e275b 100644 --- a/data/assets/scene/digitaluniverse/supernovaremnants.asset +++ b/data/assets/scene/digitaluniverse/supernovaremnants.asset @@ -41,6 +41,7 @@ local Object = { GUI = { Name = "Supernova Remnants", Path = "/Milky Way/Nebulae", + Focusable = false, Description = [[A supernova remnant is the nebulous gas left over from a supernova explosion. This gas expands at great speeds and rams into the surrounding interstellar gas. This excites the surrounding gas and causes it to glow, producing diff --git a/data/assets/scene/digitaluniverse/tully.asset b/data/assets/scene/digitaluniverse/tully.asset index ba74452a65..c9527825fc 100644 --- a/data/assets/scene/digitaluniverse/tully.asset +++ b/data/assets/scene/digitaluniverse/tully.asset @@ -59,6 +59,7 @@ local TullyGalaxies = { GUI = { Name = "Tully Galaxies", Path = "/Universe/Nearby Surveys", + Focusable = false, Description = [[The Tully Catalog is the most polished, accurate catalog of nearby galaxies. It includes over 30,000 galaxies in the local universe that surround the Milky Way. This catalog demonstrates the large-scale structure of the universe @@ -86,7 +87,7 @@ local TullyGalaxiesImages = { TransformationMatrix = transforms.Supergalactic, -- Use fixed orientation, and rotate planes based on orientation information in -- the dataset - OrientationRenderOption = "Fixed Rotation", + Billboard = "Fixed Rotation", UseOrientationData = true, Unit = "Mpc", Fading = { @@ -102,8 +103,9 @@ local TullyGalaxiesImages = { } }, GUI = { - Name = "Tully Galaxies Images", + Name = "Tully Galaxy Images", Path = "/Universe/Nearby Surveys", + Focusable = false, Description = [[Each Tully galaxy is represented by an image that represents its morphological type (spiral, elliptical, etc.). Most of these come from The Galaxy Catalog. A handful of nearby galaxies are represented by their actual images, which diff --git a/data/assets/scene/digitaluniverse/voids.asset b/data/assets/scene/digitaluniverse/voids.asset index 66dfd12df0..347d448fd4 100644 --- a/data/assets/scene/digitaluniverse/voids.asset +++ b/data/assets/scene/digitaluniverse/voids.asset @@ -26,6 +26,7 @@ local Object = { GUI = { Name = "Voids", Path = "/Universe/Nearby Surveys", + Focusable = false, Description = [[Cosmic voids are vast, empty spaces where there are either no galaxies, or very few galaxies. They are associated with cold spots in the cosmic microwave background (CMB) light, the earliest picture we have of the universe. diff --git a/data/assets/scene/digitaluniverse/white_dwarfs.asset b/data/assets/scene/digitaluniverse/white_dwarfs.asset index 4d0813d4e3..c8cbd920a2 100644 --- a/data/assets/scene/digitaluniverse/white_dwarfs.asset +++ b/data/assets/scene/digitaluniverse/white_dwarfs.asset @@ -35,6 +35,7 @@ local Object = { GUI = { Name = "White Dwarfs", Path = "/Milky Way/Stellar Remnants", + Focusable = false, Description = [[A white dwarf is the core of a dying star. These are dim objects that are roughly the size of Earth but with the desity of a sunlike star. Stars that are not massive enough to end in a neutraon star or black hole will evolve into a white diff --git a/data/assets/scene/milkyway/constellations/big_dipper.asset b/data/assets/scene/milkyway/constellations/big_dipper.asset index 1df644491b..08ef4de159 100644 --- a/data/assets/scene/milkyway/constellations/big_dipper.asset +++ b/data/assets/scene/milkyway/constellations/big_dipper.asset @@ -30,6 +30,7 @@ local BigDipper = { GUI = { Name = "Big Dipper", Path = "/Milky Way/Constellations", + Focusable = false, Description = [[This item only draws the big dipper, and not the rest of the lines of the Ursa Major constellation.]] } diff --git a/data/assets/scene/milkyway/constellations/constellation_art.asset b/data/assets/scene/milkyway/constellations/constellation_art.asset index 9a0ec35623..4b8b898efe 100644 --- a/data/assets/scene/milkyway/constellations/constellation_art.asset +++ b/data/assets/scene/milkyway/constellations/constellation_art.asset @@ -89,7 +89,7 @@ local function createConstellations(baseIdentifier, guiPath, constellationfile) Opacity = 0.1, DimInAtmosphere = true }, - Tag = { "ImageConstellation", group, "daytime_hidden" }, + Tag = { "image_constellation", "constellation_art_" .. group, "daytime_hidden" }, GUI = { Name = name .. " Image", Path = "/Milky Way/Constellations/" .. guiPath, @@ -138,7 +138,7 @@ local ShowZodiacArt = { Identifier = "os.constellation_art.ShowZodiacArt", Name = "Show zodiac", Command = [[ - openspace.fadeIn("{zodiac}") + openspace.fadeIn("{constellation_art_zodiac}") ]], Documentation = "Enables and fades up zodiac art work", GuiPath = "/Constellations/Art", @@ -149,7 +149,7 @@ local HideZodiacArt = { Identifier = "os.constellation_art.HideZodiacArt", Name = "Hide zodiac", Command = [[ - openspace.fadeOut("{zodiac}") + openspace.fadeOut("{constellation_art_zodiac}") ]], Documentation = "Fades down zodiac art work", GuiPath = "/Constellations/Art", diff --git a/data/assets/scene/milkyway/gaia/apogee.asset b/data/assets/scene/milkyway/gaia/apogee.asset index 9aee4bcc6b..74756cd390 100644 --- a/data/assets/scene/milkyway/gaia/apogee.asset +++ b/data/assets/scene/milkyway/gaia/apogee.asset @@ -53,6 +53,7 @@ local GaiaAbundanceApogee = { GUI = { Path = "/Milky Way/Gaia", Name = "Gaia Abundance Apogee", + Focusable = false, Description = "Data set of stars color coded by metallicity" } } diff --git a/data/assets/scene/milkyway/gaia/gaiastars.asset b/data/assets/scene/milkyway/gaia/gaiastars.asset index 4c2a2992f1..af1e29c59f 100644 --- a/data/assets/scene/milkyway/gaia/gaiastars.asset +++ b/data/assets/scene/milkyway/gaia/gaiastars.asset @@ -60,6 +60,7 @@ local GaiaStars = { GUI = { Name = "Gaia Stars", Path = "/Milky Way", + Focusable = false, Description = "Radial Velocity subset of GaiaDR2" } } diff --git a/data/assets/scene/milkyway/gaia/galah.asset b/data/assets/scene/milkyway/gaia/galah.asset index 2c7c3069ea..efb6815f58 100644 --- a/data/assets/scene/milkyway/gaia/galah.asset +++ b/data/assets/scene/milkyway/gaia/galah.asset @@ -53,6 +53,7 @@ local GaiaAbundanceGalah = { GUI = { Path = "/Milky Way/Gaia", Name = "Gaia Abundance Galah", + Focusable = false, Description = "Data set of stars color coded by metallicity" } } diff --git a/data/assets/scene/milkyway/milkyway/eso.asset b/data/assets/scene/milkyway/milkyway/eso.asset index 285e1c75cf..7c9315b25f 100644 --- a/data/assets/scene/milkyway/milkyway/eso.asset +++ b/data/assets/scene/milkyway/milkyway/eso.asset @@ -22,11 +22,14 @@ local Object = { Texture = textures .. "eso0932a_blend.png", Orientation = "Inside", MirrorTexture = true, - FadeOutThreshold = 0.01 + FadeOutThreshold = 0.01, + BlendingOption = "Additive", + DisableDepth = true }, GUI = { Name = "Milky Way (ESO)", Path = "/Milky Way/Milky Way", + Focusable = false, Description = "Milky Way Galaxy image (alternate)" } } diff --git a/data/assets/scene/milkyway/milkyway/volume.asset b/data/assets/scene/milkyway/milkyway/volume.asset index 642e21d4f4..a99c785910 100644 --- a/data/assets/scene/milkyway/milkyway/volume.asset +++ b/data/assets/scene/milkyway/milkyway/volume.asset @@ -14,7 +14,7 @@ local KiloParsec = 3.086E19 local MilkyWayVolume = { Identifier = "MilkyWayVolume", - Parent = transforms.SolarSystemBarycenter.Identifier, + -- No parent; this node is attached to the scene graph root Transform = { Translation = { Type = "StaticTranslation", diff --git a/data/assets/scene/milkyway/stars/denver.asset b/data/assets/scene/milkyway/stars/denver.asset index 270ebda755..61bdb4af16 100644 --- a/data/assets/scene/milkyway/stars/denver.asset +++ b/data/assets/scene/milkyway/stars/denver.asset @@ -44,7 +44,8 @@ local Object = { }, GUI = { Name = "Stars (Denver)", - Path = "/Milky Way/Stars" + Path = "/Milky Way/Stars", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/ceres/ceres.asset b/data/assets/scene/solarsystem/dwarf_planets/ceres/ceres.asset index 66a6ab71ae..f6be8f3d83 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/ceres/ceres.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/ceres/ceres.asset @@ -9,7 +9,7 @@ local Ceres = { Type = "RenderableGlobe", Radii = { 487300, 487300, 454700 } }, - Tag = { "planet_solarSystem", "planet_terrestrial", "dwarf_planet" }, + Tag = { "planet_terrestrial", "dwarf_planet" }, GUI = { Path = "/Solar System/Dwarf Planets/Ceres" } @@ -32,6 +32,7 @@ local CeresLabel = { GUI = { Name = "Ceres Label", Path = "/Solar System/Dwarf Planets/Ceres", + Focusable = false, Description = "Label for Ceres, visible at the solarsystem overview zoom level" } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/ceres/layers/colorlayers/lamo_local.asset b/data/assets/scene/solarsystem/dwarf_planets/ceres/layers/colorlayers/lamo_local.asset index d018f530df..0fea1fc0ac 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/ceres/layers/colorlayers/lamo_local.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/ceres/layers/colorlayers/lamo_local.asset @@ -15,8 +15,7 @@ local Layer = { Name = "LAMO [Local]", Enabled = asset.enabled, ZIndex = 5, - FilePath = textures .. "ceres_lamo_4096x2048.png", - CacheSettings = { Enabled = false } + FilePath = textures .. "ceres_lamo_4096x2048.png" } diff --git a/data/assets/scene/solarsystem/dwarf_planets/ceres/trail.asset b/data/assets/scene/solarsystem/dwarf_planets/ceres/trail.asset index 9d5d66e6de..6cf9d4e5c7 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/ceres/trail.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/ceres/trail.asset @@ -18,10 +18,11 @@ local CeresTrail = { Period = 1680, Resolution = 1000 }, - Tag = { "planetTrail_solarSystem", "planetTrail_dwarf" }, + Tag = { "planetTrail_dwarf" }, GUI = { Name = "Ceres Trail", - Path = "/Solar System/Dwarf Planets/Ceres" + Path = "/Solar System/Dwarf Planets/Ceres", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/ceres/transforms.asset b/data/assets/scene/solarsystem/dwarf_planets/ceres/transforms.asset index 0770c7e4fb..782932524e 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/ceres/transforms.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/ceres/transforms.asset @@ -22,6 +22,7 @@ local CeresPosition = { GUI = { Name = "Ceres Position", Path = "/Solar System/Dwarf Planets/Ceres", + Focusable = false, Hidden = true } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/eris/label.asset b/data/assets/scene/solarsystem/dwarf_planets/eris/label.asset index f3022672b7..cc209c2198 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/eris/label.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/eris/label.asset @@ -23,6 +23,7 @@ local Label = { GUI = { Name = "Eris Label", Path = "/Solar System/Dwarf Planets/Eris", + Focusable = false, Description = "Label for Eris, visible at the solarsystem overview zoom level" } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/eris/trail.asset b/data/assets/scene/solarsystem/dwarf_planets/eris/trail.asset index 418a202e70..79666f51db 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/eris/trail.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/eris/trail.asset @@ -18,7 +18,8 @@ local Trail = { Tag = { "planetTrail_dwarf" }, GUI = { Name = "Eris Trail", - Path = "/Solar System/Dwarf Planets/Eris" + Path = "/Solar System/Dwarf Planets/Eris", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/eris/transforms.asset b/data/assets/scene/solarsystem/dwarf_planets/eris/transforms.asset index 4370649bc3..1b7fceda9a 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/eris/transforms.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/eris/transforms.asset @@ -24,6 +24,7 @@ local Position = { GUI = { Name = "Eris Position", Path = "/Solar System/Dwarf Planets/Eris", + Focusable = false, Hidden = true } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/gonggong/label.asset b/data/assets/scene/solarsystem/dwarf_planets/gonggong/label.asset index 4f9849681c..9f2db95226 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/gonggong/label.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/gonggong/label.asset @@ -23,6 +23,7 @@ local Label = { GUI = { Name = "Gonggong Label", Path = "/Solar System/Dwarf Planets/Gonggong", + Focusable = false, Description = "Label for Gonggong, visible at the solarsystem overview zoom level" } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/gonggong/trail.asset b/data/assets/scene/solarsystem/dwarf_planets/gonggong/trail.asset index 940fde7b9e..0b6126f4dc 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/gonggong/trail.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/gonggong/trail.asset @@ -18,7 +18,8 @@ local Trail = { Tag = { "planetTrail_dwarf" }, GUI = { Name = "Gonggong Trail", - Path = "/Solar System/Dwarf Planets/Gonggong" + Path = "/Solar System/Dwarf Planets/Gonggong", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/gonggong/transforms.asset b/data/assets/scene/solarsystem/dwarf_planets/gonggong/transforms.asset index 32c3ecd36d..87710921a2 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/gonggong/transforms.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/gonggong/transforms.asset @@ -24,6 +24,7 @@ local Position = { GUI = { Name = "Gonggong Position", Path = "/Solar System/Dwarf Planets/Gonggong", + Focusable = false, Hidden = true } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/haumea/label.asset b/data/assets/scene/solarsystem/dwarf_planets/haumea/label.asset index 931bc317c2..4783516bad 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/haumea/label.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/haumea/label.asset @@ -23,6 +23,7 @@ local Label = { GUI = { Name = "Haumea Label", Path = "/Solar System/Dwarf Planets/Haumea", + Focusable = false, Description = "Label for Haumea, visible at the solarsystem overview zoom level" } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/haumea/trail.asset b/data/assets/scene/solarsystem/dwarf_planets/haumea/trail.asset index 4d06f318ab..51b0a1b099 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/haumea/trail.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/haumea/trail.asset @@ -19,6 +19,7 @@ local Trail = { GUI = { Name = "Haumea Trail", Path = "/Solar System/Dwarf Planets/Haumea", + Focusable = false, Description = "Trail of Haumea" } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/haumea/transforms.asset b/data/assets/scene/solarsystem/dwarf_planets/haumea/transforms.asset index b2e7bbddbc..c43b45531c 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/haumea/transforms.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/haumea/transforms.asset @@ -25,6 +25,7 @@ local Position = { GUI = { Name = "Haumea Position", Path = "/Solar System/Dwarf Planets/Haumea", + Focusable = false, Hidden = true } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/makemake/label.asset b/data/assets/scene/solarsystem/dwarf_planets/makemake/label.asset index e97d8eab3f..eda00397ff 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/makemake/label.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/makemake/label.asset @@ -23,6 +23,7 @@ local Label = { GUI = { Name = "Makemake Label", Path = "/Solar System/Dwarf Planets/Makemake", + Focusable = false, Description = "Label for Makemake, visible at the solarsystem overview zoom level" } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/makemake/trail.asset b/data/assets/scene/solarsystem/dwarf_planets/makemake/trail.asset index d9f8506ee1..569de3ad49 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/makemake/trail.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/makemake/trail.asset @@ -18,7 +18,8 @@ local Trail = { Tag = { "planetTrail_dwarf" }, GUI = { Name = "Makemake Trail", - Path = "/Solar System/Dwarf Planets/Makemake" + Path = "/Solar System/Dwarf Planets/Makemake", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/makemake/transforms.asset b/data/assets/scene/solarsystem/dwarf_planets/makemake/transforms.asset index ebc89a82d6..d3fa8db238 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/makemake/transforms.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/makemake/transforms.asset @@ -25,6 +25,7 @@ local Position = { GUI = { Name = "Makemake Position", Path = "/Solar System/Dwarf Planets/Makemake", + Focusable = false, Hidden = true } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/orcus/label.asset b/data/assets/scene/solarsystem/dwarf_planets/orcus/label.asset index d27fc95cd9..ef933cbed0 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/orcus/label.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/orcus/label.asset @@ -23,6 +23,7 @@ local Label = { GUI = { Name = "Orcus Label", Path = "/Solar System/Dwarf Planets/Orcus", + Focusable = false, Description = "Label for Orcus, visible at the solarsystem overview zoom level" } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/orcus/trail.asset b/data/assets/scene/solarsystem/dwarf_planets/orcus/trail.asset index 185e661178..41100371e2 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/orcus/trail.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/orcus/trail.asset @@ -18,6 +18,7 @@ local Trail = { Tag = { "planetTrail_dwarf" }, GUI = { Name = "Orcus Trail", + Focusable = false, Path = "/Solar System/Dwarf Planets/Orcus" } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/orcus/transforms.asset b/data/assets/scene/solarsystem/dwarf_planets/orcus/transforms.asset index 388d13f9e9..0253fc2806 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/orcus/transforms.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/orcus/transforms.asset @@ -25,6 +25,7 @@ local Position = { GUI = { Name = "Orcus Position", Path = "/Solar System/Dwarf Planets/Orcus", + Focusable = false, Hidden = true } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/pluto/charon/charon.asset b/data/assets/scene/solarsystem/dwarf_planets/pluto/charon/charon.asset index 6c7c0079c5..30d608d792 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/pluto/charon/charon.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/pluto/charon/charon.asset @@ -43,7 +43,13 @@ local Charon = { Color = { 1.0, 1.0, 0.0 } } }, - Tag = { "moon_solarSystem", "moon_dwarf", "moon_pluto", "moon_major", "moon_major_pluto" }, + Tag = { + "moon_solarSystem", + "moon_dwarf", + "moon_pluto", + "moon_major", + "moon_major_pluto" + }, GUI = { Path = "/Solar System/Dwarf Planets/Pluto/Charon" } @@ -70,6 +76,7 @@ local CharonLabel = { GUI = { Name = "Charon Label", Path = "/Solar System/Dwarf Planets/Pluto/Charon", + Focusable = false, Description = "Label for Pluto's moon Charon" } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/pluto/charon/charon_trail.asset b/data/assets/scene/solarsystem/dwarf_planets/pluto/charon/charon_trail.asset index c700e2d00f..168bc9b1dc 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/pluto/charon/charon_trail.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/pluto/charon/charon_trail.asset @@ -25,7 +25,8 @@ local CharonBarycentricTrail = { }, GUI = { Name = "Charon Barycentric Trail", - Path = "/Solar System/Dwarf Planets/Pluto/Charon" + Path = "/Solar System/Dwarf Planets/Pluto/Charon", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/pluto/minor/hydra.asset b/data/assets/scene/solarsystem/dwarf_planets/pluto/minor/hydra.asset index afd8d52428..de2cc2bdc3 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/pluto/minor/hydra.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/pluto/minor/hydra.asset @@ -46,7 +46,8 @@ local HydraTrail = { }, GUI = { Name = "Hydra Trail", - Path = "/Solar System/Dwarf Planets/Pluto/Moons/Hydra" + Path = "/Solar System/Dwarf Planets/Pluto/Moons/Hydra", + Focusable = false } } @@ -71,6 +72,7 @@ local HydraLabel = { GUI = { Name = "Hydra Label", Path = "/Solar System/Dwarf Planets/Pluto/Moons/Hydra", + Focusable = false, Description = "Label for Pluto's moon Hydra" } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/pluto/minor/kerberos.asset b/data/assets/scene/solarsystem/dwarf_planets/pluto/minor/kerberos.asset index cfea0f7392..ffb5a2f4e4 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/pluto/minor/kerberos.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/pluto/minor/kerberos.asset @@ -17,7 +17,13 @@ local Kerberos = { Type = "RenderableGlobe", Radii = { 10000, 10000, 10000 } }, - Tag = { "moon_solarSystem", "moon_dwarf", "moon_pluto", "moon_minor", "moon_minor_pluto" }, + Tag = { + "moon_solarSystem", + "moon_dwarf", + "moon_pluto", + "moon_minor", + "moon_minor_pluto" + }, GUI = { Path = "/Solar System/Dwarf Planets/Pluto/Moons/Kerberos" } @@ -46,7 +52,8 @@ local KerberosTrail = { }, GUI = { Name = "Kerberos Trail", - Path = "/Solar System/Dwarf Planets/Pluto/Moons/Kerberos" + Path = "/Solar System/Dwarf Planets/Pluto/Moons/Kerberos", + Focusable = false } } @@ -71,6 +78,7 @@ local KerberosLabel = { GUI = { Name = "Kerberos Label", Path = "/Solar System/Dwarf Planets/Pluto/Moons/Kerberos", + Focusable = false, Description = "Label for Pluto's moon Kerberos" } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/pluto/minor/nix.asset b/data/assets/scene/solarsystem/dwarf_planets/pluto/minor/nix.asset index 4ca7c37417..7ef0ed4e4e 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/pluto/minor/nix.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/pluto/minor/nix.asset @@ -17,7 +17,13 @@ local Nix = { Type = "RenderableGlobe", Radii = { 45000, 45000, 45000 } }, - Tag = { "moon_solarSystem", "moon_dwarf", "moon_pluto", "moon_minor", "moon_minor_pluto" }, + Tag = { + "moon_solarSystem", + "moon_dwarf", + "moon_pluto", + "moon_minor", + "moon_minor_pluto" + }, GUI = { Path = "/Solar System/Dwarf Planets/Pluto/Moons/Nix" } @@ -46,7 +52,8 @@ local NixTrail = { }, GUI = { Name = "Nix Trail", - Path = "/Solar System/Dwarf Planets/Pluto/Moons/Nix" + Path = "/Solar System/Dwarf Planets/Pluto/Moons/Nix", + Focusable = false } } @@ -71,6 +78,7 @@ local NixLabel = { GUI = { Name = "Nix Label", Path = "/Solar System/Dwarf Planets/Pluto/Moons/Nix", + Focusable = false, Description = "Label for Pluto's moon Nix" } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/pluto/minor/styx.asset b/data/assets/scene/solarsystem/dwarf_planets/pluto/minor/styx.asset index ecb06af177..b410ff557c 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/pluto/minor/styx.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/pluto/minor/styx.asset @@ -17,7 +17,13 @@ local Styx = { Type = "RenderableGlobe", Radii = { 45000, 45000, 45000 } }, - Tag = { "moon_solarSystem", "moon_dwarf", "moon_pluto", "moon_minor", "moon_minor_pluto" }, + Tag = { + "moon_solarSystem", + "moon_dwarf", + "moon_pluto", + "moon_minor", + "moon_minor_pluto" + }, GUI = { Path = "/Solar System/Dwarf Planets/Pluto/Moons/Styx" } @@ -46,7 +52,8 @@ local StyxTrail = { }, GUI = { Name = "Styx Trail", - Path = "/Solar System/Dwarf Planets/Pluto/Moons/Styx" + Path = "/Solar System/Dwarf Planets/Pluto/Moons/Styx", + Focusable = false } } @@ -71,6 +78,7 @@ local StyxLabel = { GUI = { Name = "Styx Label", Path = "/Solar System/Dwarf Planets/Pluto/Moons/Styx", + Focusable = false, Description = "Label for Pluto's moon Styx" } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto.asset b/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto.asset index 33cb68425d..8034f03b96 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto.asset @@ -43,7 +43,7 @@ local Pluto = { Color = { 1.0, 1.0, 0.0 } } }, - Tag = { "planet_solarSystem", "planet_terrestrial", "dwarf_planet" }, + Tag = { "planet_terrestrial", "dwarf_planet" }, GUI = { Path = "/Solar System/Dwarf Planets/Pluto" } @@ -70,6 +70,7 @@ local PlutoLabel = { GUI = { Name = "Pluto Label", Path = "/Solar System/Dwarf Planets/Pluto", + Focusable = false, Description = "Label for Pluto, visible at the solarsystem overview zoom level" } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto_trail.asset b/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto_trail.asset deleted file mode 100644 index c755a54906..0000000000 --- a/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto_trail.asset +++ /dev/null @@ -1,47 +0,0 @@ -local transforms = asset.require("./transforms") -local coreKernels = asset.require("spice/core") - - - -local PlutoTrailBarycentric = { - Identifier = "PlutoBarycentricTrail", - Parent = transforms.PlutoBarycenter.Identifier, - Renderable = { - Type = "RenderableTrailOrbit", - Translation = { - Type = "SpiceTranslation", - Target = coreKernels.ID.Pluto, - Observer = coreKernels.ID.PlutoBarycenter - }, - Color = { 0.00, 0.62, 1.00 }, - Period = 6.38723, - Resolution = 1000 - }, - Tag = { "planetTrail_solarSystem", "planetTrail_dwarf" }, - GUI = { - Name = "Pluto Barycentric Trail", - Path = "/Solar System/Dwarf Planets/Pluto", - Description = "Orbit of Pluto around its Barycenter" - } -} - - -asset.onInitialize(function() - openspace.addSceneGraphNode(PlutoTrailBarycentric) -end) - -asset.onDeinitialize(function() - openspace.removeSceneGraphNode(PlutoTrailBarycentric) -end) - -asset.export(PlutoTrailBarycentric) - - - -asset.meta = { - Name = "Pluto Barycentric Trail", - Description = "Trail of Pluto as observed by its Barycenter", - Author = "OpenSpace Team", - URL = "http://openspaceproject.com", - License = "MIT license" -} diff --git a/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto_trail_kepler.asset b/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto_trail_kepler.asset deleted file mode 100644 index e0ff0f1342..0000000000 --- a/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto_trail_kepler.asset +++ /dev/null @@ -1,55 +0,0 @@ -local transforms = asset.require("scene/solarsystem/sun/transforms") - - - -local AU = 1.496e+8 - -local PlutoKeplerianTrail = { - Identifier = "PlutoKeplerianTrail", - Parent = transforms.SunEclipJ2000.Identifier, - Renderable = { - Type = "RenderableTrailOrbit", - Enabled = false, - Translation = { - Type = "KeplerTranslation", - Eccentricity = 0.2543033082909471, - SemiMajorAxis = 39.74407237841206 * AU, - Inclination = 17.36609481151430, - AscendingNode = 110.2099981996057, - ArgumentOfPeriapsis = 114.2248569189779, - MeanAnomaly = 14.53, - Epoch = "2000 JAN 01 00:00:00", - Period = 7824380000 - }, - Color = { 0.2, 0.8, 0.3 }, - Period = 90487.27692706819, - Resolution = 1000 - }, - GUI = { - Name = "Pluto Keplerian Trail", - Path = "/Solar System/Dwarf Planets/Pluto", - Description = "Keplerian trail of Pluto. Contains full orbit" - } -} - - -asset.onInitialize(function() - openspace.addSceneGraphNode(PlutoKeplerianTrail) -end) - -asset.onDeinitialize(function() - openspace.removeSceneGraphNode(PlutoKeplerianTrail) -end) - -asset.export(PlutoKeplerianTrail) - - - -asset.meta = { - Name = "Pluto Keplerian Trail", - Description = [[Full Keplerian trail of Pluto as observed by the Sun. Data from - JPL Horizons]], - Author = "OpenSpace Team", - URL = "https://ssd.jpl.nasa.gov/sbdb.cgi?sstr=pluto", - License = "JPL/NASA" -} diff --git a/data/assets/scene/solarsystem/dwarf_planets/pluto/system.asset b/data/assets/scene/solarsystem/dwarf_planets/pluto/system.asset index bbf35ccd96..19dfbfe927 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/pluto/system.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/pluto/system.asset @@ -1,7 +1,5 @@ asset.require("./trail") asset.require("./pluto") -asset.require("./pluto_trail") -asset.require("./pluto_trail_kepler") asset.require("./charon/charon") asset.require("./charon/charon_trail") asset.require("./minor/hydra") diff --git a/data/assets/scene/solarsystem/dwarf_planets/pluto/trail.asset b/data/assets/scene/solarsystem/dwarf_planets/pluto/trail.asset index 18209e1341..0250915f1d 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/pluto/trail.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/pluto/trail.asset @@ -14,13 +14,15 @@ local PlutoBarycenterTrail = { Observer = coreKernels.ID.SolarSystemBarycenter }, Color = { 0.3, 0.7, 0.3 }, - Period = 365.25, - Resolution = 1000 + Period = 90560, + Resolution = 368, + LineLength = 0.03 }, - Tag = { "planetTrail_solarSystem", "planetTrail_dwarf" }, + Tag = { "planetTrail_dwarf" }, GUI = { Name = "Pluto Barycenter Trail", Path = "/Solar System/Dwarf Planets/Pluto", + Focusable = false, Description = [[Precise trail of Pluto from NASA SPICE data. Not containing full orbit]] } diff --git a/data/assets/scene/solarsystem/dwarf_planets/quaoar/label.asset b/data/assets/scene/solarsystem/dwarf_planets/quaoar/label.asset index 42ed67349d..c380de600b 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/quaoar/label.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/quaoar/label.asset @@ -23,6 +23,7 @@ local Label = { GUI = { Name = "Quaoar Label", Path = "/Solar System/Dwarf Planets/Quaoar", + Focusable = false, Description = "Label for Quaoar, visible at the solarsystem overview zoom level" } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/quaoar/trail.asset b/data/assets/scene/solarsystem/dwarf_planets/quaoar/trail.asset index 8ee5bcc0fc..7c5d7d13f0 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/quaoar/trail.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/quaoar/trail.asset @@ -19,6 +19,7 @@ local Trail = { GUI = { Name = "Quaoar Trail", Path = "/Solar System/Dwarf Planets/Quaoar", + Focusable = false, Description = "Trail of Quaoar" } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/quaoar/transforms.asset b/data/assets/scene/solarsystem/dwarf_planets/quaoar/transforms.asset index a4ad4ec616..2913310fb7 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/quaoar/transforms.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/quaoar/transforms.asset @@ -25,6 +25,7 @@ local Position = { GUI = { Name = "Quaoar Position", Path = "/Solar System/Dwarf Planets/Quaoar", + Focusable = false, Hidden = true } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/sedna/label.asset b/data/assets/scene/solarsystem/dwarf_planets/sedna/label.asset index 5e7f34382d..5588556b7c 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/sedna/label.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/sedna/label.asset @@ -23,6 +23,7 @@ local Label = { GUI = { Name = "Sedna Label", Path = "/Solar System/Dwarf Planets/Sedna", + Focusable = false, Description = "Label for Sedna, visible at the solarsystem overview zoom level" } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/sedna/trail.asset b/data/assets/scene/solarsystem/dwarf_planets/sedna/trail.asset index bbaa6de828..03274f22e1 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/sedna/trail.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/sedna/trail.asset @@ -19,6 +19,7 @@ local Trail = { GUI = { Name = "Sedna Trail", Path = "/Solar System/Dwarf Planets/Sedna", + Focusable = false, Description = "Trail of Sedna" } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/sedna/transforms.asset b/data/assets/scene/solarsystem/dwarf_planets/sedna/transforms.asset index ab99f667b7..2d075432c3 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/sedna/transforms.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/sedna/transforms.asset @@ -25,6 +25,7 @@ local Position = { GUI = { Name = "Sedna Position", Path = "/Solar System/Dwarf Planets/Sedna", + Focusable = false, Hidden = true } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/vesta/label.asset b/data/assets/scene/solarsystem/dwarf_planets/vesta/label.asset index 400036ae5c..ec66a23932 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/vesta/label.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/vesta/label.asset @@ -23,6 +23,7 @@ local Label = { GUI = { Name = "Vesta Label", Path = "/Solar System/Dwarf Planets/Vesta", + Focusable = false, Description = "Label for Vesta, visible at the solarsystem overview zoom level" } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/vesta/trail.asset b/data/assets/scene/solarsystem/dwarf_planets/vesta/trail.asset index 230c86c856..7460c4cfa7 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/vesta/trail.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/vesta/trail.asset @@ -19,6 +19,7 @@ local Trail = { GUI = { Name = "Vesta Trail", Path = "/Solar System/Dwarf Planets/Vesta", + Focusable = false, Description = "Trail of Vesta" } } diff --git a/data/assets/scene/solarsystem/dwarf_planets/vesta/transforms.asset b/data/assets/scene/solarsystem/dwarf_planets/vesta/transforms.asset index 9280fc674f..4e597818f3 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/vesta/transforms.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/vesta/transforms.asset @@ -5,28 +5,29 @@ local transforms = asset.require("scene/solarsystem/sun/transforms") local AU = 1.496e+8 local Translation = { - Type = "KeplerTranslation", - Eccentricity = 0.08875750498598881, - SemiMajorAxis = 2.363038212561438 * AU, - Inclination = 7.139257981928672, - AscendingNode = 103.7573001493549, - ArgumentOfPeriapsis = 151.5991639880173, - MeanAnomaly = 115.1329895974862, - Epoch = "2021 04 13 11:15:57", - Period = 1326.797192349944 * 60 * 60 * 24 + Type = "KeplerTranslation", + Eccentricity = 0.08875750498598881, + SemiMajorAxis = 2.363038212561438 * AU, + Inclination = 7.139257981928672, + AscendingNode = 103.7573001493549, + ArgumentOfPeriapsis = 151.5991639880173, + MeanAnomaly = 115.1329895974862, + Epoch = "2021 04 13 11:15:57", + Period = 1326.797192349944 * 60 * 60 * 24 } local Position = { - Identifier = "VestaPosition", - Parent = transforms.SunEclipJ2000.Identifier, - Transform = { - Translation = Translation - }, - GUI = { - Name = "Vesta Position", - Path = "/Solar System/Dwarf Planets/Vesta", - Hidden = true - } + Identifier = "VestaPosition", + Parent = transforms.SunEclipJ2000.Identifier, + Transform = { + Translation = Translation + }, + GUI = { + Name = "Vesta Position", + Path = "/Solar System/Dwarf Planets/Vesta", + Focusable = false, + Hidden = true + } } diff --git a/data/assets/scene/solarsystem/heliosphere/2012/sun_earth_2012_fieldlines_batsrus.asset b/data/assets/scene/solarsystem/heliosphere/2012/sun_earth_2012_fieldlines_batsrus.asset index 6a34d700e4..acf6983973 100644 --- a/data/assets/scene/solarsystem/heliosphere/2012/sun_earth_2012_fieldlines_batsrus.asset +++ b/data/assets/scene/solarsystem/heliosphere/2012/sun_earth_2012_fieldlines_batsrus.asset @@ -65,8 +65,9 @@ local BatsrusJ12OpenClosed = { Type = "RenderableFieldlinesSequence", SourceFolder = unzippedDataDestination.openClosed, InputFileType = "Osfls", - Color = { 0.7, 0.4, 0.0, 0.6 }, -- Default color - ColorMethod = "By Quantity", -- Color by Quantity + ShowAtAllTimes = false, + Color = { 0.7, 0.4, 0.0, 0.6 }, + ColorMethod = "By Quantity", ColorQuantity = 0, -- Temperature ColorTablePaths = { batsrusTemperatureColorTable, @@ -78,7 +79,7 @@ local BatsrusJ12OpenClosed = { ColorTableRanges = colorRanges, MaskingEnabled = true, MaskingQuantity = 4, -- Topology - MaskingRanges = { {2.5, 3.0} } -- Corresponds to closed fieldlines only + MaskingRanges = { { 2.5, 3.0 } } -- Corresponds to closed fieldlines only }, GUI = { Name = "Fieldlines BATSRUS J12 Open/Closed", @@ -95,9 +96,10 @@ local BatsrusJ12FlowLines = { Type = "RenderableFieldlinesSequence", SourceFolder = unzippedDataDestination.velocityFlow, InputFileType = "Osfls", - ColorMethod = "By Quantity", -- Color by Quantity + ShowAtAllTimes = false, + ColorMethod = "By Quantity", ColorQuantity = 3, -- Velocity - Color = { 0.7, 0.4, 0.0, 0.12 }, -- Default color + Color = { 0.7, 0.4, 0.0, 0.12 }, ColorTablePaths = { batsrusTemperatureColorTable, batsrusDensityColorTable, @@ -123,6 +125,7 @@ local BatsrusAsherStaticSeedsFlowLines = { Enabled = false, SourceFolder = unzippedDataDestination.asherStatic, InputFileType = "Osfls", + ShowAtAllTimes = false, ColorTablePaths = { batsrusTemperatureColorTable, batsrusDensityColorTable, diff --git a/data/assets/scene/solarsystem/heliosphere/2012/sun_earth_2012_fieldlines_enlil.asset b/data/assets/scene/solarsystem/heliosphere/2012/sun_earth_2012_fieldlines_enlil.asset index 336ec6d658..dd8d173ff9 100644 --- a/data/assets/scene/solarsystem/heliosphere/2012/sun_earth_2012_fieldlines_enlil.asset +++ b/data/assets/scene/solarsystem/heliosphere/2012/sun_earth_2012_fieldlines_enlil.asset @@ -1,5 +1,5 @@ asset.require("scene/solarsystem/heliosphere/2012/reset_loop_action") -local transforms = asset.require("scene/solarsystem/sun/transforms_heliosphere") +local transforms = asset.require("scene/solarsystem/heliosphere/transforms_heliosphere") @@ -61,8 +61,9 @@ local ENLILSliceEqPlane11AU1 = { Type = "RenderableFieldlinesSequence", SourceFolder = unzippedDataDestination.EqPlane011AU1, InputFileType = "Osfls", + ShowAtAllTimes = false, Color = { 0.4, 0.15, 0.4, 0.6 }, - ColorMethod = "By Quantity", -- Color by Quantity + ColorMethod = "By Quantity", ColorQuantity = 1, -- Velocity ColorTablePaths = { enlilDensityColorTable, @@ -84,8 +85,9 @@ local ENLILSliceEqPlane11AU2 = { Type = "RenderableFieldlinesSequence", SourceFolder = unzippedDataDestination.EqPlane011AU2, InputFileType = "Osfls", + ShowAtAllTimes = false, Color = { 0.4, 0.15, 0.4, 0.6 }, - ColorMethod = "By Quantity", -- Color by Quantity + ColorMethod = "By Quantity", ColorQuantity = 1, -- Velocity ColorTablePaths = { enlilDensityColorTable, @@ -107,9 +109,9 @@ local ENLILSliceLat411AU1 = { Type = "RenderableFieldlinesSequence", SourceFolder = unzippedDataDestination.Lat4011AU1, InputFileType = "Osfls", - + ShowAtAllTimes = false, Color = { 0.4, 0.15, 0.4, 0.6 }, - ColorMethod = "By Quantity", -- Color by Quantity + ColorMethod = "By Quantity", ColorQuantity = 1, -- Velocity ColorTablePaths = { enlilDensityColorTable, @@ -131,9 +133,9 @@ local ENLILSliceLat411AU2 = { Type = "RenderableFieldlinesSequence", SourceFolder = unzippedDataDestination.Lat4011AU2, InputFileType = "Osfls", - + ShowAtAllTimes = false, Color = { 0.4, 0.15, 0.4, 0.6 }, - ColorMethod = "By Quantity", -- Color by Quantity + ColorMethod = "By Quantity", ColorQuantity = 1, -- Velocity ColorTablePaths = { enlilDensityColorTable, @@ -155,6 +157,7 @@ local ENLILEarth = { Type = "RenderableFieldlinesSequence", SourceFolder = unzippedDataDestination.Earth, InputFileType = "Osfls", + ShowAtAllTimes = false, Color = { 1.0, 1.0, 1.0, 0.6 }, ColorTablePaths = { enlilDensityColorTable, @@ -176,6 +179,7 @@ local ENLILStereoA = { Type = "RenderableFieldlinesSequence", SourceFolder = unzippedDataDestination.StereoA, InputFileType = "Osfls", + ShowAtAllTimes = false, Color = { 1.0, 1.0, 1.0, 0.6 }, ColorTablePaths = { enlilDensityColorTable, diff --git a/data/assets/scene/solarsystem/heliosphere/2012/sun_earth_2012_fieldlines_pfss.asset b/data/assets/scene/solarsystem/heliosphere/2012/sun_earth_2012_fieldlines_pfss.asset index b0d83cae39..168938bf40 100644 --- a/data/assets/scene/solarsystem/heliosphere/2012/sun_earth_2012_fieldlines_pfss.asset +++ b/data/assets/scene/solarsystem/heliosphere/2012/sun_earth_2012_fieldlines_pfss.asset @@ -1,4 +1,4 @@ -local transforms = asset.require("scene/solarsystem/sun/transforms_heliosphere") +local transforms = asset.require("scene/solarsystem/heliosphere/transforms_heliosphere") @@ -53,6 +53,7 @@ local PFSS = { Type = "RenderableFieldlinesSequence", SourceFolder = PFSSPaths.SolarSoft, InputFileType = "Osfls", + ShowAtAllTimes = true, Color = { 0.35, 0.51, 0.875, 0.22 }, FlowEnabled = true, ReversedFlow = true, diff --git a/data/assets/scene/solarsystem/heliosphere/bastille_day/carrington_to_heeq_rotation.asset b/data/assets/scene/solarsystem/heliosphere/bastille_day/carrington_to_heeq_rotation.asset deleted file mode 100644 index c4607f4f9f..0000000000 --- a/data/assets/scene/solarsystem/heliosphere/bastille_day/carrington_to_heeq_rotation.asset +++ /dev/null @@ -1,26 +0,0 @@ -local CarringtonLongitudeToHEEQ180Rotation = { - -- This is a rotation matrix to go from the Carrington longitude reference frame to the - -- HEEQ180 reference frame. At the reference time, MAS_seq = 0, 2000-07-14T08:33:37.105 - -- the Carrington longitude was 309.3 degrees. - -- Difference from HEEQ => 360-309.3=50.7 (or 0-309.3 = -309.3). However this leads to - -- the same rotation matrix in the end) - -- Since OpenSpace supports HEEQ180 and not HEEQ, 180 was added or subtracted - -- => a1 = -129.3 and a2 = 230.7 - -- Rotation matrix: (cos a, -sin a, 0)(sin a, cos a, 0)(0, 0, 1) leads to the result. - Type = "FixedRotation", - XAxis = { -0.63338087262755016203262119192353, -0.77384020972650618518999944537717, 0.0 }, - YAxis = { 0.77384020972650618518999944537717, -0.63338087262755016203262119192353, 0.0 }, - ZAxis = { 0.0, 0.0, 1.0 } -} - -asset.export("CarringtonLongitudeToHEEQ180Rotation", CarringtonLongitudeToHEEQ180Rotation) - - - -asset.meta = { - Name = "Carrington Longitude To HEEQ180 Rotation", - Description = "Contains a rotation for HEEQ180 to be used by another file", - Author = "OpenSpace Team", - URL = "http://openspaceproject.com", - License = "MIT license" -} diff --git a/data/assets/scene/solarsystem/heliosphere/bastille_day/density_volume.asset b/data/assets/scene/solarsystem/heliosphere/bastille_day/density_volume.asset index 1f7dbef0e1..59a3de2b7d 100644 --- a/data/assets/scene/solarsystem/heliosphere/bastille_day/density_volume.asset +++ b/data/assets/scene/solarsystem/heliosphere/bastille_day/density_volume.asset @@ -1,4 +1,3 @@ -local propertyHelper = asset.require("util/property_helper") local sunTransforms = asset.require("scene/solarsystem/sun/transforms") local sunAsset = asset.require("scene/solarsystem/sun/sun") diff --git a/data/assets/scene/solarsystem/heliosphere/bastille_day/fieldlines.asset b/data/assets/scene/solarsystem/heliosphere/bastille_day/fieldlines.asset index 9b3d361ce5..fdc6c79f08 100644 --- a/data/assets/scene/solarsystem/heliosphere/bastille_day/fieldlines.asset +++ b/data/assets/scene/solarsystem/heliosphere/bastille_day/fieldlines.asset @@ -1,6 +1,4 @@ -local heliosphereTransforms = asset.require("scene/solarsystem/sun/transforms_heliosphere") -local propertyHelper = asset.require("util/property_helper") -local rot = asset.require("./carrington_to_heeq_rotation") +local sunTransforms = asset.require("scene/solarsystem/sun/transforms") @@ -17,12 +15,11 @@ local SunRadius = 695700000 -- Fieldlies from binaries local Fieldlines = { Identifier = "MAS-MHD-Fieldlines-bastille-day-2000", - Parent = heliosphereTransforms.HeliocentricEarthEquatorial180.Identifier, + Parent = sunTransforms.SunIAU.Identifier, -- TODO Elon: 21 April 2022. Interaction sphere should not depend on the transform scale. -- InteractionSphere = sunAsset.Sun.Renderable.Radii[1] * 1.05, InteractionSphere = 1 / SunRadius, Transform = { - Rotation = rot.CarringtonLongitudeToHEEQ180Rotation, Scale = { Type = "StaticScale", Scale = SunRadius @@ -31,17 +28,14 @@ local Fieldlines = { Renderable = { Type = "RenderableFieldlinesSequence", SourceFolder = fieldlinesDirectory, - AlphaBlendlingEnabled = false, InputFileType = "Osfls", + LineWidth = 1.0, + ShowAtAllTimes = false, + ColorQuantity = 0, ColorTablePaths = { - asset.resource("transferfunctions/density-fieldlines.txt"), - asset.resource("transferfunctions/velocity-fieldlines.txt") + asset.resource("transferfunctions/density-fieldlines.txt") }, - ColorTableRanges = { - { 0, 1000000 }, - { 100, 2000 } - }, - SimulationModel = "mas" + ColorMinMaxRange = { 0, 1000000 } }, GUI = { Path = "/Solar System/Heliosphere/Bastille Day 2000", @@ -55,23 +49,7 @@ local ToggleFieldlines = { Identifier = "os.bastilleday.fieldlines.ToggleFieldlines", Name = "Toggle fieldlines", Command = [[ - if openspace.propertyValue("Scene.MAS-MHD-Fieldlines-bastille-day-2000.Renderable.Enabled") then - openspace.setPropertyValueSingle( - "Scene.MAS-MHD-Fieldlines-bastille-day-2000.Renderable.Fade", - 0.0, - openspace.propertyValue("OpenSpaceEngine.FadeDuration"), - "Linear", - 'openspace.setPropertyValueSingle("Scene.MAS-MHD-Fieldlines-bastille-day-2000.Renderable.Enabled", false)' - ) - else - openspace.setPropertyValueSingle("Scene.MAS-MHD-Fieldlines-bastille-day-2000.Renderable.Enabled", true) - openspace.setPropertyValueSingle( - "Scene.MAS-MHD-Fieldlines-bastille-day-2000.Renderable.Fade", - 1.0, - openspace.propertyValue("OpenSpaceEngine.FadeDuration"), - "Linear" - ) - end + openspace.toggleFade("Scene.MAS-MHD-Fieldlines-bastille-day-2000.Renderable") ]], Documentation = "Toggle fieldline rendering of CME", GuiPath = "/Bastille-Day 2000", diff --git a/data/assets/scene/solarsystem/heliosphere/bastille_day/fluxnodes.asset b/data/assets/scene/solarsystem/heliosphere/bastille_day/fluxnodes.asset index cd87a530a6..e7b58bf6dd 100644 --- a/data/assets/scene/solarsystem/heliosphere/bastille_day/fluxnodes.asset +++ b/data/assets/scene/solarsystem/heliosphere/bastille_day/fluxnodes.asset @@ -1,6 +1,4 @@ -local heliosphereTransforms = asset.require("scene/solarsystem/sun/transforms_heliosphere") -local propertyHelper = asset.require("util/property_helper") -local rot = asset.require("./carrington_to_heeq_rotation") +local sunTransforms = asset.require("scene/solarsystem/sun/transforms") @@ -15,13 +13,10 @@ local fluxNodesBinaries = asset.resource({ -- FluxNodes from binaries local Fluxnodes = { Identifier = "MAS-MHD-FluxNodes-bastille-day-2000", - Parent = heliosphereTransforms.HeliocentricEarthEquatorial180.Identifier, + Parent = sunTransforms.SunIAU.Identifier, -- TODO Elon: 21 April 2022. Interaction sphere should not depend on the transform scale. -- InteractionSphere = sunAsset.Sun.Renderable.Radii[1] * 1.05, InteractionSphere = 695700000.0, - Transform = { - Rotation = rot.CarringtonLongitudeToHEEQ180Rotation - }, Renderable = { Type = "RenderableFluxNodes", SourceFolder = fluxNodesBinaries, @@ -40,23 +35,7 @@ local ToggleFluxnodes = { Identifier = "os.bastilleday.fluxnodes.ToggleFluxnodes", Name = "Toggle flux nodes", Command = [[ - if openspace.propertyValue("Scene.MAS-MHD-FluxNodes-bastille-day-2000.Renderable.Enabled") then - openspace.setPropertyValueSingle( - "Scene.MAS-MHD-FluxNodes-bastille-day-2000.Renderable.Fade", - 0.0, - openspace.propertyValue("OpenSpaceEngine.FadeDuration"), - "Linear", - 'openspace.setPropertyValueSingle("Scene.MAS-MHD-FluxNodes-bastille-day-2000.Renderable.Enabled", false)' - ) - else - openspace.setPropertyValueSingle("Scene.MAS-MHD-FluxNodes-bastille-day-2000.Renderable.Enabled", true) - openspace.setPropertyValueSingle( - "Scene.MAS-MHD-FluxNodes-bastille-day-2000.Renderable.Fade", - 1.0, - openspace.propertyValue("OpenSpaceEngine.FadeDuration"), - "Linear" - ) - end + openspace.toggleFade("Scene.MAS-MHD-FluxNodes-bastille-day-2000.Renderable") ]], Documentation = "Toggle flux node rendering of CME", GuiPath = "/Bastille-Day 2000", diff --git a/data/assets/scene/solarsystem/heliosphere/bastille_day/fluxnodescutplane.asset b/data/assets/scene/solarsystem/heliosphere/bastille_day/fluxnodescutplane.asset index b9724a9190..3d4031cbc9 100644 --- a/data/assets/scene/solarsystem/heliosphere/bastille_day/fluxnodescutplane.asset +++ b/data/assets/scene/solarsystem/heliosphere/bastille_day/fluxnodescutplane.asset @@ -1,6 +1,5 @@ -local propertyHelper = asset.require("util/property_helper") -local transforms = asset.require("scene/solarsystem/sun/transforms_heliosphere") -local rot = asset.require("./carrington_to_heeq_rotation") +local transforms = asset.require("scene/solarsystem/sun/transforms") +local transformsHelio = asset.require("scene/solarsystem/heliosphere/transforms_heliosphere") @@ -21,13 +20,10 @@ local TexturesPathMeridial = asset.resource({ local EquatorialCutplane = { Identifier = "EquatorialCutplane-bastille-day-2000", - Parent = transforms.HeliocentricEarthEquatorial180.Identifier, + Parent = transforms.SunIAU.Identifier, -- TODO Elon: 21 April 2022. Interaction sphere should not depend on the transform scale. -- InteractionSphere = sunAsset.Sun.Renderable.Radii[1] * 1.05, InteractionSphere = 695700000.0, - Transform = { - Rotation = rot.CarringtonLongitudeToHEEQ180Rotation - }, Renderable = { Type = "RenderablePlaneTimeVaryingImage", Size = 157000000000, @@ -47,7 +43,7 @@ local EquatorialCutplane = { local MeridialCutplane = { Identifier = "MeridialCutplane-bastille-day-2000", - Parent = transforms.HeliocentricEarthEquatorial180.Identifier, + Parent = transformsHelio.HeliocentricEarthEquatorial180.Identifier, -- TODO Elon: 21 April 2022. Interaction sphere should not depend on the transform scale. -- InteractionSphere = sunAsset.Sun.Renderable.Radii[1] * 1.05, InteractionSphere = 695700000, @@ -78,23 +74,7 @@ local ToggleEquatorial = { Identifier = "os.bastilleday.fluxnodescutplane.ToggleEquatorial", Name = "Toggle equatorial cutplane", Command = [[ - if openspace.propertyValue("Scene.EquatorialCutplane-bastille-day-2000.Renderable.Enabled") then - openspace.setPropertyValueSingle( - "Scene.EquatorialCutplane-bastille-day-2000.Renderable.Fade", - 0.0, - openspace.propertyValue("OpenSpaceEngine.FadeDuration"), - "Linear", - 'openspace.setPropertyValueSingle("Scene.EquatorialCutplane-bastille-day-2000.Renderable.Enabled", false)' - ) - else - openspace.setPropertyValueSingle("Scene.EquatorialCutplane-bastille-day-2000.Renderable.Enabled", true) - openspace.setPropertyValueSingle( - "Scene.EquatorialCutplane-bastille-day-2000.Renderable.Fade", - 1.0, - openspace.propertyValue("OpenSpaceEngine.FadeDuration"), - "Linear" - ) - end + openspace.toggleFade("Scene.EquatorialCutplane-bastille-day-2000.Renderable") ]], Documentation = "Toggle equatorial cutplane of CME", GuiPath = "/Bastille-Day 2000", @@ -105,23 +85,7 @@ local ToggleMeridial = { Identifier = "os.bastilleday.fluxnodescutplane.ToggleMeridial", Name = "Toggle meridial cutplane", Command = [[ - if openspace.propertyValue("Scene.MeridialCutplane-bastille-day-2000.Renderable.Enabled") then - openspace.setPropertyValueSingle( - "Scene.MeridialCutplane-bastille-day-2000.Renderable.Fade", - 0.0, - openspace.propertyValue("OpenSpaceEngine.FadeDuration"), - "Linear", - 'openspace.setPropertyValueSingle("Scene.MeridialCutplane-bastille-day-2000.Renderable.Enabled", false)' - ) - else - openspace.setPropertyValueSingle("Scene.MeridialCutplane-bastille-day-2000.Renderable.Enabled", true) - openspace.setPropertyValueSingle( - "Scene.MeridialCutplane-bastille-day-2000.Renderable.Fade", - 1.0, - openspace.propertyValue("OpenSpaceEngine.FadeDuration"), - "Linear" - ) - end + openspace.toggleFade("Scene.MeridialCutplane-bastille-day-2000.Renderable") ]], Documentation = "Toggle meridial cutplane of CME", GuiPath = "/Bastille-Day 2000", diff --git a/data/assets/scene/solarsystem/heliosphere/bastille_day/fluxnodeslegend.asset b/data/assets/scene/solarsystem/heliosphere/bastille_day/fluxnodeslegend.asset index 43427b2bff..5f011beecb 100644 --- a/data/assets/scene/solarsystem/heliosphere/bastille_day/fluxnodeslegend.asset +++ b/data/assets/scene/solarsystem/heliosphere/bastille_day/fluxnodeslegend.asset @@ -19,23 +19,7 @@ local ToggleLegend = { Identifier = "os.bastilleday.fluxnodelegend.ToggleLegend", Name = "Toggle the legend image", Command = [[ - if openspace.propertyValue("ScreenSpace.LegendFluxNodes-bastille-day-2000.Enabled") then - openspace.setPropertyValueSingle( - "ScreenSpace.LegendFluxNodes-bastille-day-2000.Fade", - 0.0, - openspace.propertyValue("OpenSpaceEngine.FadeDuration"), - "Linear", - 'openspace.setPropertyValueSingle("ScreenSpace.LegendFluxNodes-bastille-day-2000.Enabled", false)' - ) - else - openspace.setPropertyValueSingle("ScreenSpace.LegendFluxNodes-bastille-day-2000.Enabled", true) - openspace.setPropertyValueSingle( - "ScreenSpace.LegendFluxNodes-bastille-day-2000.Fade", - 1.0, - openspace.propertyValue("OpenSpaceEngine.FadeDuration"), - "Linear" - ) - end + openspace.toggleFade("ScreenSpace.LegendFluxNodes-bastille-day-2000") ]], Documentation = "Toggle the legend image", GuiPath = "/Bastille-Day 2000", @@ -46,13 +30,7 @@ local HideLegend = { Identifier = "os.bastilleday.fluxnodelegend.HideLegend", Name = "Hides the legend image", Command = [[ - openspace.setPropertyValueSingle( - "ScreenSpace.LegendFluxNodes-bastille-day-2000.Fade", - 0.0, - openspace.propertyValue("OpenSpaceEngine.FadeDuration"), - "Linear", - 'openspace.setPropertyValueSingle("ScreenSpace.LegendFluxNodes-bastille-day-2000.Enabled", false)' - ) + openspace.fadeOut("ScreenSpace.LegendFluxNodes-bastille-day-2000") ]], Documentation = "Hides the legend image", GuiPath = "/Bastille-Day 2000", diff --git a/data/assets/scene/solarsystem/heliosphere/bastille_day/magnetogram_textures.asset b/data/assets/scene/solarsystem/heliosphere/bastille_day/magnetogram_textures.asset index 9117ffe63b..35bcab60af 100644 --- a/data/assets/scene/solarsystem/heliosphere/bastille_day/magnetogram_textures.asset +++ b/data/assets/scene/solarsystem/heliosphere/bastille_day/magnetogram_textures.asset @@ -43,8 +43,7 @@ asset.onInitialize(function() Description = "", FilePath = imagename, Enabled = false, - ZIndex = 100, - CacheSettings = { Enabled = false } + ZIndex = 100 } ) end diff --git a/data/assets/scene/solarsystem/heliosphere/todayssun/fieldlines.asset b/data/assets/scene/solarsystem/heliosphere/todayssun/fieldlines.asset new file mode 100644 index 0000000000..ea0461fee4 --- /dev/null +++ b/data/assets/scene/solarsystem/heliosphere/todayssun/fieldlines.asset @@ -0,0 +1,203 @@ +local transforms = asset.require("scene/solarsystem/heliosphere/transforms_heliosphere") + + + +local transferFunctions = asset.resource({ + Type = "HttpSynchronization", + Name = "Today's Sun Transfer Functions", + Identifier = "todayssun_transferfunctions", + Version = 1 +}) + + +local windSpeedPolarityColorTable = transferFunctions .. "polarity_spec.txt" +local subEarthLevelColorTable = transferFunctions .. "subearth_spec.txt" +local currentSheetColorTable = transferFunctions .. "currentsheet_spec.txt" +local opennessColorTable = transferFunctions .."openness_spec.txt" + +local infoURL = "https://iswaa-webservice1.ccmc.gsfc.nasa.gov/IswaSystemWebApp/DataInfoServlet?id=" +local dataURL = "https://iswaa-webservice1.ccmc.gsfc.nasa.gov/IswaSystemWebApp/FilesInRangeServlet?dataID=" + +local sunRadius = 695700000.0 + +local fieldlinesSCS = { + Identifier = "WSA_54_Fieldlines_SCS_OI", + Parent = transforms.WSAOffset60.Identifier, + Transform = { + Scale = { + Type = "StaticScale", + Scale = sunRadius + }, + }, + Renderable = { + Type = "RenderableFieldlinesSequence", + InputFileType = "Osfls", + LoadingType = "DynamicDownloading", + InfoURL = infoURL, + DataURL = dataURL, + DataID = 2286, + ShowAtAllTimes = false, + ColorMethod = "By Quantity", + ColorQuantity = 0, -- Polarity & solar wind speed + ColorTablePaths = { + windSpeedPolarityColorTable, + currentSheetColorTable + }, + ColorTableRanges = { + { -1.0, 1.0 }, + { 0.0, 1.0 } + } + }, + GUI = { + Name = "Fieldlines: Corona SCS (Out-In Tracing)", + Path = "/Solar System/Heliosphere/WSA Coronal Model", + Description = [[WSA 5.4 real-time output of the fieldline trace from the Schatten + Current Sheet model (SCS) outer boundary at 21.5 Rs to the source surface at 2.5 Rs + using GONGZ as input.]], + Focusable = false + } +} + +local fieldlinesOI = { + Identifier = "WSA_54_Fieldlines_PFSS_OI", + Parent = transforms.WSAOffset60.Identifier, + Transform = { + Scale = { + Type = "StaticScale", + Scale = sunRadius + }, + }, + Renderable = { + Type = "RenderableFieldlinesSequence", + InputFileType = "Osfls", + LoadingType = "DynamicDownloading", + InfoURL = infoURL, + DataURL = dataURL, + DataID = 2285, + ShowAtAllTimes = false, + ColorMethod = "By Quantity", + ColorQuantity = 0, -- Polarity & solar wind speed + ColorTablePaths = { + windSpeedPolarityColorTable, + currentSheetColorTable + }, + ColorTableRanges = { + { -1.0, 1.0 }, + { 0.0, 1.0 } + }, + }, + GUI = { + Name = "Fieldlines: Corona PFSS (Out-In Tracing)", + Path = "/Solar System/Heliosphere/WSA Coronal Model", + Description = [[WSA 5.4 real-time output of the fieldline trace from the source + surface to the solar surface using GONGZ as input. PFSS is the Potential Field + Source Surface model, a part of WSA.]], + Focusable = false + } +} + +local fieldlinesIO = { + Identifier = "WSA_54_Fieldlines_PFSS_IO", + Parent = transforms.WSAOffset60.Identifier, + Transform = { + Scale = { + Type = "StaticScale", + Scale = sunRadius + }, + }, + Renderable = { + Type = "RenderableFieldlinesSequence", + InputFileType = "Osfls", + LoadingType = "DynamicDownloading", + InfoURL = infoURL, + DataURL = dataURL, + DataID = 2284, + ShowAtAllTimes = false, + ColorMethod = "By Quantity", + ColorQuantity = 0, -- Open/closed lines + ColorTablePaths = { + opennessColorTable + }, + ColorTableRanges = { + { 0.0, 2.0 } + }, + }, + GUI = { + Name = "Fieldlines: Corona PFSS (In-Out Tracing)", + Path = "/Solar System/Heliosphere/WSA Coronal Model", + Description = [[WSA 5.4 real-time output of the fieldline trace from the solar surface + outwards using GONGZ as input. PFSS is the Potential Field Source Surface model, a + part of WSA.]], + Focusable = false + } +} + +local fieldlinesEarth = { + Identifier = "WSA_54_Fieldlines_Earth", + Parent = transforms.WSAOffset60.Identifier, + Transform = { + Scale = { + Type = "StaticScale", + Scale = sunRadius + }, + }, + Renderable = { + Type = "RenderableFieldlinesSequence", + InputFileType = "Osfls", + LoadingType = "DynamicDownloading", + InfoURL = infoURL, + DataURL = dataURL, + DataID = 2287, + ShowAtAllTimes = false, + ColorMethod = "By Quantity", + ColorQuantity = 0, -- Polarity + ColorTablePaths = { + windSpeedPolarityColorTable, + subEarthLevelColorTable + }, + ColorTableRanges = { + { 0.0, 1.0 }, + { 0.0, 2.0 } + }, + }, + GUI = { + Name = "Fieldlines: Tracing from Earth", + Path = "/Solar System/Heliosphere/WSA Coronal Model", + Description = [[WSA 5.4 real-time output of the field line trace from Earth using GONGZ + as input.]], + Focusable = false + } +} + + +asset.onInitialize(function() + openspace.addSceneGraphNode(fieldlinesSCS) + openspace.addSceneGraphNode(fieldlinesOI) + openspace.addSceneGraphNode(fieldlinesIO) + openspace.addSceneGraphNode(fieldlinesEarth) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(fieldlinesEarth) + openspace.removeSceneGraphNode(fieldlinesIO) + openspace.removeSceneGraphNode(fieldlinesOI) + openspace.removeSceneGraphNode(fieldlinesSCS) +end) + +asset.export(fieldlinesSCS) +asset.export(fieldlinesOI) +asset.export(fieldlinesIO) +asset.export(fieldlinesEarth) + + + +asset.meta = { + Name = "WSA 5.4. Streaming Field Line Data Dynamically", + Version = "1.0", + Description = [[Downloading data from the WSA 5.4 simulation model, showing the dynamic + Sun at any point. It includes .osfls files (OpenSpace FieldLine Sequence) for field + lines.]], + Author = "CCMC", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/scene/solarsystem/heliosphere/todayssun/grid.asset b/data/assets/scene/solarsystem/heliosphere/todayssun/grid.asset new file mode 100644 index 0000000000..b083d82a6b --- /dev/null +++ b/data/assets/scene/solarsystem/heliosphere/todayssun/grid.asset @@ -0,0 +1,128 @@ +local transforms = asset.require("scene/solarsystem/heliosphere/transforms_heliosphere") +local sunTransforms = asset.require("scene/solarsystem/sun/transforms") + + + +-- Slightly bigger size than the sphere radius to allow grid lines to not clip into sphere +-- since the lines themselfs are not curved +local gridSizeRadius = 7.0E8 + +local CarringtonPrimeMeridian = { + Identifier = "CarringtonPrimeMeridian", + Parent = sunTransforms.SunIAU.Identifier, + Transform = { + Translation = { + Type = "StaticTranslation", + -- A shift to only show an arc on one side of the sun + Position = { 3500000.0, 0.0, 0.0 } + }, + Rotation = { + Type = "StaticRotation", + Rotation = { 0.0, 0.0, -math.rad(90) } + }, + Scale = { + Type = "StaticScale", + -- Slightly smaller than grid size, to make the arc look better together with the + -- translation in x + Scale = 6.98E8 + } + }, + Renderable = { + Type = "RenderableSphericalGrid", + Size = gridSizeRadius, + Color = { 1.0, 0.0, 0.0 }, + LineWidth = 2.0, + LongSegments = 2, + LatSegments = 64 + }, + GUI = { + Name = "Carrington Prime Meridian", + Path = "/Solar System/Heliosphere", + Description = [[An arc showing the Carrington prime meridian of the Sun. + The line from pole to pole at 0 degree longitude.]], + Focusable = false + } +} + +local WSA_GridSlice = { + Identifier = "WSA_GridSlice", + Parent = transforms.HeliocentricEarthEquatorial.Identifier, + Transform = { + Rotation = { + Type = "StaticRotation", + Rotation = { 0.0, 0.0, -math.rad(90) } + }, + Scale = { + Type = "StaticScale", + Scale = gridSizeRadius + } + }, + Renderable = { + Type = "RenderableSphericalGrid", + Size = gridSizeRadius, + Color = { 0.8, 0.8, 0.8 }, + LineWidth = 2.0, + LongSegments = 2, + LatSegments = 64 + }, + GUI = { + Name = "Solar Longitude Facing the Earth", + Path = "/Solar System/Heliosphere", + Description = [[An arc on the Sun surface from pole to pole that always faces Earth.]], + Focusable = false + } +} + +local WSA_Grid10Degrees = { + Identifier = "WSA_Grid10Degrees", + Parent = transforms.HeliocentricEarthEquatorial.Identifier, + Transform = { + Scale = { + Type = "StaticScale", + Scale = gridSizeRadius + } + }, + Renderable = { + Type = "RenderableSphericalGrid", + Size = gridSizeRadius, + Color = { 0.035, 0.675, 0.255 }, + LineWidth = 1.0, + Segments = 36 + }, + GUI = { + Name = "Grid on Sun", + Path = "/Solar System/Heliosphere", + Description = [[A grid aligned with the Sun-Earth line, with a 10-degree + separation between line segments by default.]], + Focusable = false + } +} + + +asset.onInitialize(function() + openspace.addSceneGraphNode(CarringtonPrimeMeridian) + openspace.addSceneGraphNode(WSA_GridSlice) + openspace.addSceneGraphNode(WSA_Grid10Degrees) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(WSA_Grid10Degrees) + openspace.removeSceneGraphNode(WSA_GridSlice) + openspace.removeSceneGraphNode(CarringtonPrimeMeridian) +end) + +asset.export(CarringtonPrimeMeridian) +asset.export(WSA_GridSlice) +asset.export(WSA_Grid10Degrees) + + + +asset.meta = { + Name = "Real-time Sun Grid Lines", + Version = "1.0", + Description = [[Grids that help show the Sun's orientation and rotation in relation to + Earth, including the Carrington prime meridian and Earth-facing longitudes.]], + Author = "CCMC", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/scene/solarsystem/heliosphere/todayssun/mission.asset b/data/assets/scene/solarsystem/heliosphere/todayssun/mission.asset new file mode 100644 index 0000000000..93dc8315db --- /dev/null +++ b/data/assets/scene/solarsystem/heliosphere/todayssun/mission.asset @@ -0,0 +1,49 @@ +local timeNow = openspace.time.currentWallTime() +local Mission = { + Identifier = "WSA", + Name = "The WSA Simulation Model", + TimeRange = { Start = "2022 DEC 09 16:14:00", End = timeNow }, + Description = [[ + This visualization shows the Sun's magnetic field using data from the WSA + (Wang-Sheeley-Arge) simulation model. The field lines trace the Sun's magnetic field. + Some loop back into the Sun (closed, shown in yellow), while others stream into space + (open). The simulation data throughout this visualization is colored red for positive + values and blue for negative. Red field lines indicate that the direction of the field + is pointing away from the sun and blue that it is pointing inward toward the Sun. The + direction of the field is opposite on either side of whats called the heliospheric + current sheet. On the Sun's surface, white and black indicate areas of positive and + negative magnetic polarity, respectively. Understanding these fields is critical: + solar activity like Coronal Mass Ejections (CMEs) can disrupt satellites, power grids, + and pose risks to astronauts and spacecraft throughout the solar system. All + simulation data in this profile is fetched live, giving you the latest view of our + dynamic Sun. + ]], + Milestones = { + { + Name = "Version 5.4", + Date = "2022 DEC 09 16:14:00", + Description = [[For version 5.4 of WSA fieldline data and solar surfaces from end of + 2022 until today.]] + } + } +} + + +asset.onInitialize(function() + openspace.loadMission(Mission) +end) + +asset.onDeinitialize(function() + openspace.unloadMission(Mission) +end) + + + +asset.meta = { + Name = "Overview information panel - Mission panel", + Description = [[This mission file provides information about the simulation model + WSA.]], + Author = "CCMC", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/scene/solarsystem/heliosphere/todayssun/sun_earth_line.asset b/data/assets/scene/solarsystem/heliosphere/todayssun/sun_earth_line.asset new file mode 100644 index 0000000000..d136f57209 --- /dev/null +++ b/data/assets/scene/solarsystem/heliosphere/todayssun/sun_earth_line.asset @@ -0,0 +1,43 @@ +local earth = asset.require("scene/solarsystem/planets/earth/earth") +local sun = asset.require("scene/solarsystem/sun/sun") + + + +local SunEarthLine = { + Identifier = "RenderableNodeLine_Sun_Earth", + Renderable = { + Type = "RenderableNodeLine", + StartNode = sun.Sun.Identifier, + EndNode = earth.Earth.Identifier + }, + GUI = { + Name = "Sun-Earth Line", + Path = "/Solar System/Heliosphere", + Description = [[A line between the Sun and the Earth to help with spatial + orientation.]], + Focusable = false + } +} + + +asset.onInitialize(function() + openspace.addSceneGraphNode(SunEarthLine) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(SunEarthLine) +end) + +asset.export("NodeLine", SunEarthLine) + + + +asset.meta = { + Name = "Sun-Earth Line", + Version = "1.0", + Description = [[A line between the Sun and the Earth to help with spatial + orientation.]], + Author = "CCMC", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/scene/solarsystem/heliosphere/todayssun/surfaces.asset b/data/assets/scene/solarsystem/heliosphere/todayssun/surfaces.asset new file mode 100644 index 0000000000..5ff39e52a3 --- /dev/null +++ b/data/assets/scene/solarsystem/heliosphere/todayssun/surfaces.asset @@ -0,0 +1,285 @@ +local transforms = asset.require("scene/solarsystem/heliosphere/transforms_heliosphere") + + + +local transferFunctions = asset.resource({ + Type = "HttpSynchronization", + Name = "Today's Sun Transfer Functions", + Identifier = "todayssun_transferfunctions", + Version = 1 +}) + + +local blueBlackRed = transferFunctions .. "blue-black-red.txt" + +local infoURL = "https://iswaa-webservice1.ccmc.gsfc.nasa.gov/IswaSystemWebApp/DataInfoServlet?id=" +local dataURL = "https://iswaa-webservice1.ccmc.gsfc.nasa.gov/IswaSystemWebApp/FilesInRangeServlet?dataID=" + +local sunRadius = 695700000 +-- This small 0.2% increase is an arbitrary number but necessary to make sure it is not +-- within the Sun sphere +local extendedRadius = sunRadius * 1.002 +local fiveSunRadius = sunRadius * 5 +local outerBoundary = sunRadius * 21.5 +-- Slightly bigger radii to prevent z fighting rendering artifact compared to GONG-Z +local extendedRadiusAdapt = extendedRadius * 1.00002 +local fiveSunRadiusAdapt = fiveSunRadius * 1.00002 +local outerBoundaryAdapt = outerBoundary * 1.00002 + +local WSA_54_Magnetic_Field_GONGZ_5_Rs = { + Identifier = "WSA_54_Magnetic_Field_GONGZ_5_Rs", + Parent = transforms.WSAOffset60.Identifier, + Renderable = { + Type = "RenderableTimeVaryingFitsSphere", + Size = fiveSunRadius, + Orientation = "Both", + LoadingType = "DynamicDownloading", + InfoURL = infoURL, + DataURL = dataURL, + DataID = 2148, + FitsLayer = 0, + LayerNames = { + ['0'] = "Coronal Magnetic Field at 5 Solar Radii (nT)" + }, + LayerMinMaxCapValues = { + ['0'] = { -5000.0, 5000.0 } + }, + ColorMap = blueBlackRed, + UseColorMap = false, + ShowPastFirstAndLastFile = false, + Segments = 132 + }, + GUI = { + Name = "Magnetic Field at 5Rs (GONG-Z)", + Path = "/Solar System/Heliosphere/WSA Coronal Model", + Description = [[Texture sequence of simulation model WSA 5.4, showing the coronal + magnetic field on a sphere at 5 solar radii. Output: FITS files using GONG-Z Maps + (RADOUT = 5.0).]], + Focusable = false + } +} + +local WSA_54_Magnetic_Field_ADAPT_5_Rs = { + Identifier = "WSA_54_Magnetic_Field_ADAPT_5_Rs", + Parent = transforms.HeliocentricEarthEquatorial180.Identifier, + Renderable = { + Type = "RenderableTimeVaryingFitsSphere", + Size = fiveSunRadiusAdapt, + Orientation = "Both", + LoadingType = "DynamicDownloading", + InfoURL = infoURL, + DataURL = dataURL, + DataID = 2149, + FitsLayer = 0, + LayerNames = { + ['0'] = "Coronal Magnetic Field at 5 Solar Radii (nT)" + }, + LayerMinMaxCapValues = { + ['0'] = { -5000.0, 5000.0 } + }, + ColorMap = blueBlackRed, + UseColorMap = false, + ShowPastFirstAndLastFile = false, + Segments = 132 + }, + GUI = { + Name = "Magnetic Field at 5Rs (GONG ADAPT)", + Path = "/Solar System/Heliosphere/WSA Coronal Model", + Description = [[Texture sequence of simulation model WSA 5.4, showing the coronal + magnetic field on a sphere at 5 solar radii. Output: FITS file using + ADAPT GONG realization 000 to 011 Maps (RADOUT = 5.0).]], + Focusable = false + } +} + +local WSA_54_Magnetograms_GONGZ = { + Identifier = "WSA_54_Magnetograms_GONGZ", + Parent = transforms.WSAOffset60.Identifier, + Renderable = { + Type = "RenderableTimeVaryingFitsSphere", + Size = extendedRadius, + LoadingType = "DynamicDownloading", + InfoURL = infoURL, + DataURL = dataURL, + DataID = 2148, + FitsLayer = 4, + LayerNames = { + ['1'] = "Flux tube expansion factor evaluated at the source surface", + ['4'] = "Observed Photospheric Field (Gauss)", + ['5'] = "Distance from open field footpoint to nearest coronal boundary (deg)", + ['6'] = [[Open (1,2,3) and closed (0) regions on the photosphere [1=in-to-out + tracing; 2=out-to-in tracing; 3=both] (no units)]], + ['7'] = "Distance to current sheet at outer boundary (degrees)" + }, + LayerMinMaxCapValues = { + ['1'] = { 0.0, 50.0 }, + ['4'] = { -50.0, 50.0 }, + ['5'] = { 0.0, 30.0 }, + ['6'] = { 0.0, 4.0 }, + ['7'] = { 0.0, 90.0 } + }, + ColorMap = blueBlackRed, + UseColorMap = false, + ShowPastFirstAndLastFile = false, + Segments = 132 + }, + GUI = { + Name = "Solar Surface (GONG-Z)", + Path = "/Solar System/Heliosphere/WSA Coronal Model", + Description = [[Texture sequence of simulation model WSA 5.4, showing data on the + solar surface with multiple options in the list under Texture Layer Options. Output: + FITS files using GONG-Z Maps (RADOUT = 5.0).]], + Focusable = false + } +} + +local WSA_54_Magnetograms_ADAPT = { + Identifier = "WSA_54_Magnetograms_ADAPT", + Parent = transforms.HeliocentricEarthEquatorial180.Identifier, + Renderable = { + Type = "RenderableTimeVaryingFitsSphere", + Size = extendedRadiusAdapt, + LoadingType = "DynamicDownloading", + InfoURL = infoURL, + DataURL = dataURL, + DataID = 2149, + FitsLayer = 4, + LayerNames = { + ['1'] = "Flux tube expansion factor evaluated at the source surface", + ['4'] = "Observed Photospheric Field (Gauss)", + ['5'] = "Distance from open field footpoint to nearest coronal boundary (deg)", + ['6'] = [[Open (1,2,3) and closed (0) regions on the photosphere [1=in-to-out + tracing; 2=out-to-in tracing; 3=both] (no units)]], + ['7'] = "Distance to current sheet at outer boundary (degrees)" + }, + LayerMinMaxCapValues = { + ['1'] = { 0.0, 50.0 }, + ['4'] = { -50.0, 50.0 }, + ['5'] = { 0.0, 30.0 }, + ['6'] = { 0.0, 4.0 }, + ['7'] = { 0.0, 90.0 } + }, + ColorMap = blueBlackRed, + UseColorMap = false, + ShowPastFirstAndLastFile = false, + Segments = 132 + }, + GUI = { + Name = "Solar Surface (GONG ADAPT)", + Path = "/Solar System/Heliosphere/WSA Coronal Model", + Description = [[Texture sequence of simulation model WSA 5.4, showing data on the + solar surface with multiple options in the list under Texture Layer Options. Output: + FITS file using ADAPT GONG realization 000 to 011 Maps (RADOUT = 5.0).]], + Focusable = false + } +} + +local WSA_Velocity_Adapt_Outer_Boundary = { + Identifier = "WSA_54_velocity_ADAPT_Outer_Boundary", + Parent = transforms.HeliocentricEarthEquatorial180.Identifier, + Renderable = { + Type = "RenderableTimeVaryingFitsSphere", + Size = outerBoundaryAdapt, + LoadingType = "DynamicDownloading", + Orientation = "Both", + InfoURL = infoURL, + DataURL = dataURL, + DataID = 2218, + FitsLayer = 1, + LayerNames = { + ['0'] = "Coronal Magnetic Field at 21.5 Solar Radii (nT)", + ['1'] = "Solar Wind Speed at 21.5 Solar Radii (km/s)" + }, + LayerMinMaxCapValues = { + ['0'] = { -200.0, 200.0 }, + ['1'] = { 200.0, 850.0 } + }, + ColorMap = blueBlackRed, + ShowPastFirstAndLastFile = false, + Segments = 132 + }, + GUI = { + Name = "Velocity at Outer Boundary (GONG-ADAPT)", + Path = "/Solar System/Heliosphere/WSA Coronal Model", + Description = [[Texture sequence of simulation model WSA 5.4, showing data on a sphere + at the outer boundary of the simulation model, either solar wind speed or coronal + magnetic field. Output: FITS file using ADAPT GONG realization 000-011 Maps + (RADOUT = 21.5).]], + Focusable = false + } +} + +local WSA_Velocity_Gongz_Outer_Boundary = { + Identifier = "WSA_54_velocity_GONGZ_Outer_Boundary", + Parent = transforms.WSAOffset60.Identifier, + Renderable = { + Type = "RenderableTimeVaryingFitsSphere", + Size = outerBoundary, + Orientation = "Both", + LoadingType = "DynamicDownloading", + InfoURL = infoURL, + DataURL = dataURL, + DataID = 2217, + FitsLayer = 1, + LayerNames = { + ['0'] = "Coronal Magnetic Field at 21.5 Solar Radii (nT)", + ['1'] = "Solar Wind Speed at 21.5 Solar Radii (km/s)" + }, + LayerMinMaxCapValues = { + ['0'] = { -200.0, 200.0 }, + ['1'] = { 200.0, 850.0 } + }, + ColorMap = blueBlackRed, + ShowPastFirstAndLastFile = false, + Segments = 132 + }, + GUI = { + Name = "Velocity at Outer Boundary (GONG-Z)", + Path = "/Solar System/Heliosphere/WSA Coronal Model", + Description = [[Texture sequence of simulation model WSA 5.4, showing data on a sphere + at the outer boundary of the simulation model, either solar wind speed or coronal + magnetic field. Output: FITS file using GONG-Z Maps (RADOUT = 21.5).]], + Focusable = false + } +} + + +asset.onInitialize(function() + openspace.addSceneGraphNode(WSA_54_Magnetic_Field_GONGZ_5_Rs) + openspace.addSceneGraphNode(WSA_54_Magnetic_Field_ADAPT_5_Rs) + openspace.addSceneGraphNode(WSA_54_Magnetograms_GONGZ) + openspace.addSceneGraphNode(WSA_54_Magnetograms_ADAPT) + openspace.addSceneGraphNode(WSA_Velocity_Adapt_Outer_Boundary) + openspace.addSceneGraphNode(WSA_Velocity_Gongz_Outer_Boundary) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(WSA_Velocity_Gongz_Outer_Boundary) + openspace.removeSceneGraphNode(WSA_Velocity_Adapt_Outer_Boundary) + openspace.removeSceneGraphNode(WSA_54_Magnetograms_ADAPT) + openspace.removeSceneGraphNode(WSA_54_Magnetograms_GONGZ) + openspace.removeSceneGraphNode(WSA_54_Magnetic_Field_ADAPT_5_Rs) + openspace.removeSceneGraphNode(WSA_54_Magnetic_Field_GONGZ_5_Rs) +end) + +asset.export(WSA_54_Magnetic_Field_GONGZ_5_Rs) +asset.export(WSA_54_Magnetic_Field_ADAPT_5_Rs) +asset.export(WSA_54_Magnetograms_GONGZ) +asset.export(WSA_54_Magnetograms_ADAPT) +asset.export(WSA_Velocity_Adapt_Outer_Boundary) +asset.export(WSA_Velocity_Gongz_Outer_Boundary) + + + +asset.meta = { + Name = "WSA 5.4. Streaming Surface Data Dynamically", + Version = "1.0", + Description = [[Downloading data from the WSA 5.4 simulation model, showing the dynamic + Sun at any point. It includes .fits files for solar surface data. GONG-Z is the + zero-corrected synoptic surface magnetic maps from the Global Oscillation Network + Group, while GONG-ADAPT is a model based on GONG, where ADAPT stands for Air Force + Data Assimilative Photospheric Flux Transport.]], + Author = "CCMC", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/scene/solarsystem/sun/transforms_heliosphere.asset b/data/assets/scene/solarsystem/heliosphere/transforms_heliosphere.asset similarity index 84% rename from data/assets/scene/solarsystem/sun/transforms_heliosphere.asset rename to data/assets/scene/solarsystem/heliosphere/transforms_heliosphere.asset index 45e9828964..c7ac379bf0 100644 --- a/data/assets/scene/solarsystem/sun/transforms_heliosphere.asset +++ b/data/assets/scene/solarsystem/heliosphere/transforms_heliosphere.asset @@ -23,6 +23,8 @@ local HeliocentricEarthEquatorial180 = { GUI = { Name = "Heliocentric Earth Equatorial 180", Path = "/Solar System/Sun", + Focusable = false, + Hidden = true, Description = [[ - X-Y plane is the solar equator of date, therefore, the +Z axis is the primary vector and it is aligned to the Sun's north pole of date. @@ -35,8 +37,7 @@ local HeliocentricEarthEquatorial180 = { - +Y axis completes the right-handed system. - - the origin of this frame is the Sun's center of mass.]], - Hidden = true + - the origin of this frame is the Sun's center of mass.]] } } @@ -53,6 +54,8 @@ local HeliocentricEarthEquatorial = { GUI = { Name = "Heliocentric Earth Equatorial", Path = "/Solar System/Sun", + Focusable = false, + Hidden = true, Description = [[ - X-Y plane is the solar equator of date, therefore, the +Z axis is the primary vector and it is aligned to the Sun's north pole of date. @@ -65,8 +68,7 @@ local HeliocentricEarthEquatorial = { - +Y axis completes the right-handed system. - - the origin of this frame is the Sun's center of mass.]], - Hidden = true + - the origin of this frame is the Sun's center of mass.]] } } @@ -83,6 +85,8 @@ local HeliocentricEarthEcliptic = { GUI = { Name = "Heliocentric Earth Ecliptic", Path = "/Solar System/Sun", + Focusable = false, + Hidden = true, Description = [[ - X-Y plane is defined by the Earth Mean Ecliptic plane of date, therefore, the +Z axis is the primary vector,and it defined as the normal vector to the Ecliptic plane that points toward the @@ -93,7 +97,24 @@ local HeliocentricEarthEcliptic = { - +Y axis completes the right-handed system. - - the origin of this frame is the Sun's center of mass.]], + - the origin of this frame is the Sun's center of mass.]] + } +} + +local WSAOffset60 = { + Identifier = "WSAOffset60", + Parent = HeliocentricEarthEquatorial.Identifier, + Transform = { + Rotation = { + Type = "StaticRotation", + Rotation = { 0, 0, -math.rad(60) } + } + }, + GUI = { + Name = "WSA Data Offset 60 Degrees", + Path = "/Solar System/Sun", + Description = [[WSA outputs (FITS files) have the Sun-Earth line 60 degrees shifted + from the edge. This scene graph node handles that transformation.]], Hidden = true } } @@ -106,9 +127,11 @@ asset.onInitialize(function() openspace.addSceneGraphNode(HeliocentricEarthEquatorial180) openspace.addSceneGraphNode(HeliocentricEarthEquatorial) openspace.addSceneGraphNode(HeliocentricEarthEcliptic) + openspace.addSceneGraphNode(WSAOffset60) end) asset.onDeinitialize(function() + openspace.removeSceneGraphNode(WSAOffset60) openspace.removeSceneGraphNode(HeliocentricEarthEcliptic) openspace.removeSceneGraphNode(HeliocentricEarthEquatorial) openspace.removeSceneGraphNode(HeliocentricEarthEquatorial180) @@ -120,12 +143,14 @@ end) asset.export(HeliocentricEarthEquatorial180) asset.export(HeliocentricEarthEquatorial) asset.export(HeliocentricEarthEcliptic) +asset.export(WSAOffset60) asset.meta = { Name = "Sun Transform, HEE, HEEQ and HEEQ180", - Description = "Sun transform: HEE, HEEQ and HEEQ180", + Description = [[Sun transform: HEE, HEEQ, HEEQ180 and a 60-degree fixed rotation that WSA + is using.]], Author = "CCMC", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/interstellar/3i_atlas.asset b/data/assets/scene/solarsystem/interstellar/3i_atlas.asset new file mode 100644 index 0000000000..8097ed4a2c --- /dev/null +++ b/data/assets/scene/solarsystem/interstellar/3i_atlas.asset @@ -0,0 +1,104 @@ +local sunTransforms = asset.require("scene/solarsystem/sun/transforms") + + + +local trajectory = asset.resource({ + Name = "3I/ATLAS Trajectory", + Type = "HttpSynchronization", + Identifier = "atlas_horizons", + Version = 1 +}) + + +local AtlasTrail = { + Identifier = "3I_AtlasTrail", + Parent = sunTransforms.SolarSystemBarycenter.Identifier, + Renderable = { + Type = "RenderableTrailTrajectory", + Translation = { + Type = "HorizonsTranslation", + HorizonsTextFile = trajectory .. "i3_atlas.hrz" + }, + Color = { 0.85, 0.85, 0.0 }, + StartTime = "2020 JUL 01 00:00:00", + EndTime = "2030 JUL 01 00:00:00", + SampleInterval = openspace.time.secondsPerDay() / 2 + }, + GUI = { + Name = "3I/ATLAS Trail", + Path = "/Solar System/Interstellar/ATLAS", + Focusable = false, + Description = [[Trail of 3I/ATLAS from 2020 JUL 01 00:00:00 to 2030 JUL 01 00:00:00. + Data from JPL Horizons.]] + } +} + +local AtlasPosition = { + Identifier = "3I_AtlasPosition", + Parent = sunTransforms.SolarSystemBarycenter.Identifier, + Transform = { + Translation = { + Type = "HorizonsTranslation", + HorizonsTextFile = trajectory .. "i3_atlas.hrz" + } + }, + GUI = { + Name = "3I/ATLAS", + Path = "/Solar System/Interstellar/ATLAS", + Description = [[Position of 3I/ATLAS from 2020 JUL 01 00:00:00 to 2030 JUL 01 + 00:00:00. Data from JPL Horizons.]] + } +} + +local AtlasLabel = { + Identifier = "3I_AtlasLabel", + Parent = AtlasPosition.Identifier, + Renderable = { + Type = "RenderableLabel", + Enabled = false, + Text = "3I/ATLAS", + FontSize = 70.0, + Size = 8.50, + MinMaxSize = { 1, 50 }, + OrientationOption = "Camera View Direction", + BlendMode = "Additive", + EnableFading = true, + FadeUnit = "au", + FadeDistances = { 1.5, 50.0 }, + FadeWidths = { 1.0, 40.0 } + }, + Tag = { "solarsystem_labels" }, + GUI = { + Name = "3I/ATLAS Label", + Path = "/Solar System/Interstellar/ATLAS", + Focusable = false + } +} + + +asset.onInitialize(function() + openspace.addSceneGraphNode(AtlasPosition) + openspace.addSceneGraphNode(AtlasTrail) + openspace.addSceneGraphNode(AtlasLabel) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(AtlasLabel) + openspace.removeSceneGraphNode(AtlasTrail) + openspace.removeSceneGraphNode(AtlasPosition) +end) + +asset.export(AtlasPosition) +asset.export(AtlasTrail) +asset.export(AtlasLabel) + + + +asset.meta = { + Name = "3I/ATLAS", + Description = [[This asset contains the trail and position of 3I/ATLAS from 2020 + JUL 01 00:00:00 to 2030 JUL 01 00:00:00. Data from JPL Horizons.]], + Author = "OpenSpace Team", + URL = "https://ssd.jpl.nasa.gov/horizons.cgi", + License = "NASA" +} diff --git a/data/assets/scene/solarsystem/interstellar/c-2019_q4_borisov.asset b/data/assets/scene/solarsystem/interstellar/c-2019_q4_borisov.asset index 63179278e5..a0bbc6b5fe 100644 --- a/data/assets/scene/solarsystem/interstellar/c-2019_q4_borisov.asset +++ b/data/assets/scene/solarsystem/interstellar/c-2019_q4_borisov.asset @@ -24,14 +24,15 @@ local C2019Q4BorisovTrail = { -- End time: 2050-Jan-01 00:00:00 (last data point) -- Step size: 1 day }, - Color = { 0.9, 0.9, 0.0 }, + Color = { 0.15, 0.9, 0.15 }, StartTime = "2015 JAN 01 00:00:00", EndTime = "2050 JAN 01 00:00:00", SampleInterval = openspace.time.secondsPerDay() }, GUI = { - Name = "C/2019 Q4 Borisov Trail", - Path = "/Solar System/Interstellar", + Name = "2I/Borisov Trail", + Path = "/Solar System/Interstellar/Borisov", + Focusable = false, Description = [[Trail of C-2019 Q4 Borisov from 2015 JAN 01 00:00:00 to 2050 JAN 01 00:00:00. Data from JPL Horizons]] } @@ -47,26 +48,54 @@ local C2019Q4BorisovPosition = { } }, GUI = { - Name = "C/2019 Q4 Borisov", - Path = "/Solar System/Interstellar", + Name = "2I/Borisov", + Path = "/Solar System/Interstellar/Borisov", Description = [[Position of C-2019 Q4 Borisov from 2015 JAN 01 00:00:00 to 2050 JAN 01 00:00:00. Data from JPL Horizons]] } } +local C2019Q4BorisovLabel = { + Identifier = "C2019Q4BorisovLabel", + Parent = C2019Q4BorisovPosition.Identifier, + Renderable = { + Type = "RenderableLabel", + Enabled = false, + Text = "2I/Borisov", + FontSize = 70.0, + Size = 8.50, + MinMaxSize = { 1, 50 }, + OrientationOption = "Camera View Direction", + BlendMode = "Additive", + EnableFading = true, + FadeUnit = "au", + FadeDistances = { 1.5, 50.0 }, + FadeWidths = { 1.0, 40.0 } + }, + Tag = { "solarsystem_labels" }, + GUI = { + Name = "2I/Borisov Label", + Path = "/Solar System/Interstellar/Borisov", + Focusable = false + } +} + asset.onInitialize(function() openspace.addSceneGraphNode(C2019Q4BorisovPosition) openspace.addSceneGraphNode(C2019Q4BorisovTrail) + openspace.addSceneGraphNode(C2019Q4BorisovLabel) end) asset.onDeinitialize(function() + openspace.removeSceneGraphNode(C2019Q4BorisovLabel) openspace.removeSceneGraphNode(C2019Q4BorisovTrail) openspace.removeSceneGraphNode(C2019Q4BorisovPosition) end) asset.export(C2019Q4BorisovPosition) asset.export(C2019Q4BorisovTrail) +asset.export(C2019Q4BorisovLabel) diff --git a/data/assets/scene/solarsystem/interstellar/oumuamua.asset b/data/assets/scene/solarsystem/interstellar/oumuamua.asset index 28ba280136..ff3690bc61 100644 --- a/data/assets/scene/solarsystem/interstellar/oumuamua.asset +++ b/data/assets/scene/solarsystem/interstellar/oumuamua.asset @@ -24,14 +24,15 @@ local OumuamuaTrail = { -- End time: 2050-Jan-01 00:00:00 (last data point) -- Step size: 1 day }, - Color = { 0.9, 0.9, 0.0 }, + Color = { 0.85, 0.1, 0.85 }, StartTime = "2014 JAN 01 00:00:00", EndTime = "2050 JAN 01 00:00:00", SampleInterval = openspace.time.secondsPerDay() }, GUI = { - Name = "'Oumuamua Trail", - Path = "/Solar System/Interstellar", + Name = "1I/'Oumuamua Trail", + Path = "/Solar System/Interstellar/'Oumuamua", + Focusable = false, Description = [[Trail of 'Oumuamua from 2014 JAN 01 00:00:00 to 2050 JAN 01 00:00:00. Data from JPL Horizons]] } @@ -47,26 +48,54 @@ local OumuamuaPosition = { } }, GUI = { - Name = "'Oumuamua", - Path = "/Solar System/Interstellar", + Name = "1I/'Oumuamua", + Path = "/Solar System/Interstellar/'Oumuamua", Description = [[Position of 'Oumuamua from 2014 JAN 01 00:00:00 to 2050 JAN 01 00:00:00. Data from JPL Horizons]] } } +local OumuamuaLabel = { + Identifier = "OumuamuaLabel", + Parent = OumuamuaPosition.Identifier, + Renderable = { + Type = "RenderableLabel", + Enabled = false, + Text = "1I/'Oumuamua", + FontSize = 70.0, + Size = 8.50, + MinMaxSize = { 1, 50 }, + OrientationOption = "Camera View Direction", + BlendMode = "Additive", + EnableFading = true, + FadeUnit = "au", + FadeDistances = { 1.5, 50.0 }, + FadeWidths = { 1.0, 40.0 } + }, + Tag = { "solarsystem_labels" }, + GUI = { + Name = "1I/'Oumuamua Label", + Path = "/Solar System/Interstellar/'Oumuamua", + Focusable = false + } +} + asset.onInitialize(function() openspace.addSceneGraphNode(OumuamuaPosition) openspace.addSceneGraphNode(OumuamuaTrail) + openspace.addSceneGraphNode(OumuamuaLabel) end) asset.onDeinitialize(function() + openspace.removeSceneGraphNode(OumuamuaLabel) openspace.removeSceneGraphNode(OumuamuaTrail) openspace.removeSceneGraphNode(OumuamuaPosition) end) asset.export(OumuamuaPosition) asset.export(OumuamuaTrail) +asset.export(OumuamuaLabel) diff --git a/data/assets/scene/solarsystem/missions/apollo/11/apollo11.asset b/data/assets/scene/solarsystem/missions/apollo/11/apollo11.asset index f41ca6553d..2a620933ab 100644 --- a/data/assets/scene/solarsystem/missions/apollo/11/apollo11.asset +++ b/data/assets/scene/solarsystem/missions/apollo/11/apollo11.asset @@ -1,7 +1,7 @@ asset.require("../actions") asset.require("./actions") local sun = asset.require("scene/solarsystem/sun/transforms") -local moonTransforms = asset.require("scene/solarsystem/planets/earth/moon/moon") +local moon = asset.require("scene/solarsystem/planets/earth/moon/moon") local descentKeyframes = asset.require("./lem_descent") local descentRotationKeyframes = asset.require("./lem_descent_rotation") local kernels = asset.require("./kernels") @@ -28,7 +28,7 @@ local lemModel = asset.resource({ local Apollo11Position = { Identifier = "Apollo11Position", - Parent = moonTransforms.Moon.Identifier, + Parent = moon.Moon.Identifier, TimeFrame = { Type = "TimeFrameInterval", Start = "1969 JUL 19 19:38:29.183", @@ -83,7 +83,7 @@ local Apollo11Model = { local Apollo11MoonTrail = { Identifier = "Apollo11MoonTrail", - Parent = moonTransforms.Moon.Identifier, + Parent = moon.Moon.Identifier, Renderable = { Type = "RenderableTrailTrajectory", Enabled = false, @@ -93,7 +93,7 @@ local Apollo11MoonTrail = { Observer = coreKernels.ID.Moon, Frame = coreKernels.Frame.Moon }, - Color = { 0.180000,0.510000,0.750000 }, + Color = { 0.18, 0.51, 0.75 }, StartTime = "1969 JUL 19 19:38:29.183", EndTime = "1969 JUL 22 04:55:35.183", SampleInterval = 60, @@ -101,7 +101,8 @@ local Apollo11MoonTrail = { }, GUI = { Name = "Apollo 11 Moon Orbits", - Path = "/Solar System/Missions/Apollo/11" + Path = "/Solar System/Missions/Apollo/11", + Focusable = false } } @@ -131,12 +132,12 @@ local lemRotation = { local Apollo11LemTrail = { Identifier = "Apollo11LemTrail", - Parent = moonTransforms.Moon.Identifier, + Parent = moon.Moon.Identifier, Renderable = { Type = "RenderableTrailTrajectory", Enabled = false, Translation = lemTranslation, - Color = { 0.780000,0.940000,0.340000 }, + Color = { 0.78, 0.94, 0.34 }, StartTime = "1969 JUL 20 19:10:25.183", EndTime = "1969 JUL 20 20:17:46.183", SampleInterval = 2, @@ -144,13 +145,14 @@ local Apollo11LemTrail = { }, GUI = { Name = "Apollo 11 Lunar Lander Trail", - Path = "/Solar System/Missions/Apollo/11" + Path = "/Solar System/Missions/Apollo/11", + Focusable = false } } local Apollo11LemPosition = { Identifier = "Apollo11LemPosition", - Parent = moonTransforms.Moon.Identifier, + Parent = moon.Moon.Identifier, TimeFrame = { Type = "TimeFrameInterval", Start = "1969 JUL 20 19:10:25.183" @@ -261,3 +263,14 @@ asset.export(Apollo11LemDescentModel) asset.export(Apollo11LemLandedModel) asset.export(Apollo11MoonTrail) asset.export(Apollo11LemTrail) + + + +asset.meta = { + Name = "Apollo 11", + Description = [[A meta asset that will include all of the other assets to show the + Apollo 11 launch, orbit, and landing sequence.]], + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/scene/solarsystem/missions/apollo/11/kernels.asset b/data/assets/scene/solarsystem/missions/apollo/11/kernels.asset index 7a7e60f90b..84c3dfdff0 100644 --- a/data/assets/scene/solarsystem/missions/apollo/11/kernels.asset +++ b/data/assets/scene/solarsystem/missions/apollo/11/kernels.asset @@ -34,3 +34,14 @@ end) asset.export("ID", ID) asset.export("Frame", Frame) + + + +asset.meta = { + Name = "Apollo 11 Kernel", + Description = [[This asset downloads and provides the kernels needed for the Apollo 11 + launch, trans-lunar injection, and moon orbit.]], + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/scene/solarsystem/missions/apollo/11/lem.asset b/data/assets/scene/solarsystem/missions/apollo/11/lem.asset index 7fb4e8fc6b..3cc16d0f15 100644 --- a/data/assets/scene/solarsystem/missions/apollo/11/lem.asset +++ b/data/assets/scene/solarsystem/missions/apollo/11/lem.asset @@ -1,5 +1,5 @@ local sun = asset.require("scene/solarsystem/sun/transforms") -local moon_asset = asset.require("scene/solarsystem/planets/earth/moon/moon") +local moon = asset.require("scene/solarsystem/planets/earth/moon/moon") @@ -13,11 +13,11 @@ local lem_model = asset.resource({ local Apollo11Lem = { Identifier = "Apollo11Lem", - Parent = moon_asset.Moon.Identifier, + Parent = moon.Moon.Identifier, Transform = { Translation = { Type = "GlobeTranslation", - Globe = moon_asset.Moon.Identifier, + Globe = moon.Moon.Identifier, Longitude = 23.47306, Latitude = 0.67402, Altitude = -1927.65, @@ -25,7 +25,7 @@ local Apollo11Lem = { }, Rotation = { Type = "GlobeRotation", - Globe = moon_asset.Moon.Identifier, + Globe = moon.Moon.Identifier, Longitude = 23.47306, Latitude = 0.67402 } @@ -77,3 +77,14 @@ end) asset.export(Apollo11Lem) asset.export(Apollo11LemModel) + + + +asset.meta = { + Name = "Apollo 11 Lunar Module", + Description = [[This asset provides a 3D model of the Apollo Lunar Module/Lunar + Excursion Module.]], + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/scene/solarsystem/missions/apollo/11/lem_descent.asset b/data/assets/scene/solarsystem/missions/apollo/11/lem_descent.asset index b4863a37bb..20a6119d26 100644 --- a/data/assets/scene/solarsystem/missions/apollo/11/lem_descent.asset +++ b/data/assets/scene/solarsystem/missions/apollo/11/lem_descent.asset @@ -1,3 +1,4 @@ +local moon = asset.require("scene/solarsystem/planets/earth/moon/moon") -- The following keyframe data was converted from the_last_four_minutes_2019-06-09.kml, -- which is available at http://apollo.mem-tek.com/GoogleMoonKMZ.html @@ -15,7 +16,7 @@ In the conversion, some assumptions and simplifications were made: local keyframes = { ["1969-07-20T20:13:40"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.64480784327766, Latitude = 0.6899960896998255, Altitude = -1546.3568594681615, @@ -23,7 +24,7 @@ local keyframes = { }, ["1969-07-20T20:13:41"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.64371058653857, Latitude = 0.6878218095380976, Altitude = -1565.4215164947534, @@ -31,7 +32,7 @@ local keyframes = { }, ["1969-07-20T20:13:42"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.64182673932963, Latitude = 0.6868724573827948, Altitude = -1565.4215164947534, @@ -39,7 +40,7 @@ local keyframes = { }, ["1969-07-20T20:13:43"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.64054706630478, Latitude = 0.6858670898943581, Altitude = -1579.0391286566048, @@ -47,7 +48,7 @@ local keyframes = { }, ["1969-07-20T20:13:44"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.63636509003987, Latitude = 0.6869318608730292, Altitude = -1579.0391286566048, @@ -55,7 +56,7 @@ local keyframes = { }, ["1969-07-20T20:13:45"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.63333610553231, Latitude = 0.6875049989808152, Altitude = -1584.4861735213453, @@ -63,7 +64,7 @@ local keyframes = { }, ["1969-07-20T20:13:46"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.630258198415152, Latitude = 0.6879251024075629, Altitude = -1587.2096959537155, @@ -71,7 +72,7 @@ local keyframes = { }, ["1969-07-20T20:13:47"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.62944534804935, Latitude = 0.6868614912680597, Altitude = -1592.656740818456, @@ -79,7 +80,7 @@ local keyframes = { }, ["1969-07-20T20:13:48"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.62679291745059, Latitude = 0.6859161360075229, Altitude = -1604.9125917641222, @@ -87,7 +88,7 @@ local keyframes = { }, ["1969-07-20T20:13:49"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.624085315638872, Latitude = 0.685126212476227, Altitude = -1619.8919651421588, @@ -95,7 +96,7 @@ local keyframes = { }, ["1969-07-20T20:13:50"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.62142772795633, Latitude = 0.6848656185526153, Altitude = -1630.7860548716399, @@ -103,7 +104,7 @@ local keyframes = { }, ["1969-07-20T20:13:51"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.617193313827283, Latitude = 0.6849603490017026, Altitude = -1630.7860548716399, @@ -111,7 +112,7 @@ local keyframes = { }, ["1969-07-20T20:13:52"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.61543137875974, Latitude = 0.68523470439912, Altitude = -1629.4242936554547, @@ -119,7 +120,7 @@ local keyframes = { }, ["1969-07-20T20:13:53"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.61158202958536, Latitude = 0.6853852597026965, Altitude = -1633.5095773040102, @@ -127,7 +128,7 @@ local keyframes = { }, ["1969-07-20T20:13:54"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.60991413189263, Latitude = 0.6852537398149626, Altitude = -1643.041905817306, @@ -135,7 +136,7 @@ local keyframes = { }, ["1969-07-20T20:13:55"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.607915527643012, Latitude = 0.6853963551830907, Altitude = -1662.106562843898, @@ -143,7 +144,7 @@ local keyframes = { }, ["1969-07-20T20:13:56"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.605996916437142, Latitude = 0.6830167672762936, Altitude = -1663.4683240600832, @@ -151,7 +152,7 @@ local keyframes = { }, ["1969-07-20T20:13:57"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.6027345854584, Latitude = 0.6824580715414034, Altitude = -1671.09418687072, @@ -159,7 +160,7 @@ local keyframes = { }, ["1969-07-20T20:13:58"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.60047452065999, Latitude = 0.6837230890353062, Altitude = -1671.638891357194, @@ -167,7 +168,7 @@ local keyframes = { }, ["1969-07-20T20:13:59"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.598006245556462, Latitude = 0.6851039272779041, Altitude = -1670.277130141009, @@ -175,7 +176,7 @@ local keyframes = { }, ["1969-07-20T20:14:00"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.594980604909782, Latitude = 0.6859011120513393, Altitude = -1683.8947423028603, @@ -183,7 +184,7 @@ local keyframes = { }, ["1969-07-20T20:14:01"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.595085912567033, Latitude = 0.685405665002322, Altitude = -1698.874115680897, @@ -191,7 +192,7 @@ local keyframes = { }, ["1969-07-20T20:14:02"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.5930664955042, Latitude = 0.6852493785380211, Altitude = -1701.597638113267, @@ -199,7 +200,7 @@ local keyframes = { }, ["1969-07-20T20:14:03"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.591385100243283, Latitude = 0.6848676328581234, Altitude = -1709.768205410378, @@ -207,7 +208,7 @@ local keyframes = { }, ["1969-07-20T20:14:04"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.58888799865371, Latitude = 0.6847945134519827, Altitude = -1717.9387727074889, @@ -215,7 +216,7 @@ local keyframes = { }, ["1969-07-20T20:14:05"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.58707895840121, Latitude = 0.6847997274847563, Altitude = -1720.662295139859, @@ -223,7 +224,7 @@ local keyframes = { }, ["1969-07-20T20:14:06"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.585134523523262, Latitude = 0.6844679679748537, Altitude = -1726.1093400045995, @@ -231,7 +232,7 @@ local keyframes = { }, ["1969-07-20T20:14:07"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.58309233633901, Latitude = 0.6845115405154798, Altitude = -1730.194623653155, @@ -239,7 +240,7 @@ local keyframes = { }, ["1969-07-20T20:14:08"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.581800658763132, Latitude = 0.6837790677972603, Altitude = -1737.0034297340808, @@ -247,7 +248,7 @@ local keyframes = { }, ["1969-07-20T20:14:09"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.580055660445762, Latitude = 0.6831436064664251, Altitude = -1741.0887133826361, @@ -255,7 +256,7 @@ local keyframes = { }, ["1969-07-20T20:14:10"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.57863282556605, Latitude = 0.6828140286921376, Altitude = -1749.259280679747, @@ -263,7 +264,7 @@ local keyframes = { }, ["1969-07-20T20:14:11"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.57640031861404, Latitude = 0.6825176811105468, Altitude = -1751.9828031121174, @@ -271,7 +272,7 @@ local keyframes = { }, ["1969-07-20T20:14:12"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.57398679174075, Latitude = 0.6826876185178852, Altitude = -1750.6210418959322, @@ -279,7 +280,7 @@ local keyframes = { }, ["1969-07-20T20:14:13"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.57156483164977, Latitude = 0.6825035088375115, Altitude = -1758.7916091930429, @@ -287,7 +288,7 @@ local keyframes = { }, ["1969-07-20T20:14:14"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.568805614344672, Latitude = 0.6825830127392937, Altitude = -1764.2386540577836, @@ -295,7 +296,7 @@ local keyframes = { }, ["1969-07-20T20:14:15"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.56712274763365, Latitude = 0.6821390846562359, Altitude = -1764.2386540577836, @@ -303,7 +304,7 @@ local keyframes = { }, ["1969-07-20T20:14:16"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.56530723506546, Latitude = 0.6815597518028071, Altitude = -1772.4092213548943, @@ -311,7 +312,7 @@ local keyframes = { }, ["1969-07-20T20:14:17"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.56412162578659, Latitude = 0.6811736246098009, Altitude = -1773.7709825710795, @@ -319,7 +320,7 @@ local keyframes = { }, ["1969-07-20T20:14:18"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.56276962682385, Latitude = 0.6808738576281527, Altitude = -1779.2180274358202, @@ -327,7 +328,7 @@ local keyframes = { }, ["1969-07-20T20:14:19"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.560994966586822, Latitude = 0.6806433210749815, Altitude = -1781.9415498681901, @@ -335,7 +336,7 @@ local keyframes = { }, ["1969-07-20T20:14:20"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.55943927760013, Latitude = 0.680762500394614, Altitude = -1788.7503559491158, @@ -343,7 +344,7 @@ local keyframes = { }, ["1969-07-20T20:14:21"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.55808185917876, Latitude = 0.6806932677701746, Altitude = -1788.205651462642, @@ -351,7 +352,7 @@ local keyframes = { }, ["1969-07-20T20:14:22"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.556393791415733, Latitude = 0.6811207130416086, Altitude = -1791.4738783814862, @@ -359,7 +360,7 @@ local keyframes = { }, ["1969-07-20T20:14:23"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.55496480157647, Latitude = 0.6814204204715102, Altitude = -1792.8356395976714, @@ -367,7 +368,7 @@ local keyframes = { }, ["1969-07-20T20:14:24"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.55306742293409, Latitude = 0.6817752241315425, Altitude = -1795.5591620300418, @@ -375,7 +376,7 @@ local keyframes = { }, ["1969-07-20T20:14:25"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.55137129589691, Latitude = 0.6815869620825672, Altitude = -1802.3679681109675, @@ -383,7 +384,7 @@ local keyframes = { }, ["1969-07-20T20:14:26"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.54977453252549, Latitude = 0.681089420496018, Altitude = -1805.0914905433376, @@ -391,7 +392,7 @@ local keyframes = { }, ["1969-07-20T20:14:27"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.548083879890072, Latitude = 0.6807962459602379, Altitude = -1807.8150129757078, @@ -399,7 +400,7 @@ local keyframes = { }, ["1969-07-20T20:14:28"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.546540200146502, Latitude = 0.6805000865197504, Altitude = -1810.5385354080781, @@ -407,7 +408,7 @@ local keyframes = { }, ["1969-07-20T20:14:29"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.54516644867878, Latitude = 0.6804026508636472, Altitude = -1815.9855802728187, @@ -415,7 +416,7 @@ local keyframes = { }, ["1969-07-20T20:14:30"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.54408346592703, Latitude = 0.6805503084088244, Altitude = -1817.3473414890038, @@ -423,7 +424,7 @@ local keyframes = { }, ["1969-07-20T20:14:31"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.54339758182375, Latitude = 0.6804859303352504, Altitude = -1818.709102705189, @@ -431,7 +432,7 @@ local keyframes = { }, ["1969-07-20T20:14:32"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.54194570925206, Latitude = 0.6803064377127922, Altitude = -1821.4326251375592, @@ -439,7 +440,7 @@ local keyframes = { }, ["1969-07-20T20:14:33"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.54085221251783, Latitude = 0.6801546546560774, Altitude = -1824.9732042996407, @@ -447,7 +448,7 @@ local keyframes = { }, ["1969-07-20T20:14:34"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.53954140597472, Latitude = 0.6797325898259152, Altitude = -1827.696726732011, @@ -455,7 +456,7 @@ local keyframes = { }, ["1969-07-20T20:14:35"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.537934104316932, Latitude = 0.679569186740729, Altitude = -1831.7820103805664, @@ -463,7 +464,7 @@ local keyframes = { }, ["1969-07-20T20:14:36"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.53689199133522, Latitude = 0.6794114031790662, Altitude = -1833.6884760832256, @@ -471,7 +472,7 @@ local keyframes = { }, ["1969-07-20T20:14:37"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.53536814560564, Latitude = 0.6791732992510942, Altitude = -1836.9567030020698, @@ -479,7 +480,7 @@ local keyframes = { }, ["1969-07-20T20:14:38"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.53395331216349, Latitude = 0.6792039275673737, Altitude = -1839.4078731912032, @@ -487,7 +488,7 @@ local keyframes = { }, ["1969-07-20T20:14:39"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.53275788877434, Latitude = 0.6790059399149831, Altitude = -1840.497282164151, @@ -495,7 +496,7 @@ local keyframes = { }, ["1969-07-20T20:14:40"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.531279977460432, Latitude = 0.6788794363528592, Altitude = -1844.5825658127067, @@ -503,7 +504,7 @@ local keyframes = { }, ["1969-07-20T20:14:41"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.52959475512685, Latitude = 0.6788906739797406, Altitude = -1845.9443270288918, @@ -511,7 +512,7 @@ local keyframes = { }, ["1969-07-20T20:14:42"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.52769228385669, Latitude = 0.6787279693068425, Altitude = -1848.123144974788, @@ -519,7 +520,7 @@ local keyframes = { }, ["1969-07-20T20:14:43"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.52685377337869, Latitude = 0.6787634478561919, Altitude = -1850.8466674071583, @@ -527,7 +528,7 @@ local keyframes = { }, ["1969-07-20T20:14:44"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.526284004538702, Latitude = 0.6785694853441325, Altitude = -1853.0254853530546, @@ -535,7 +536,7 @@ local keyframes = { }, ["1969-07-20T20:14:45"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.5258419320743, Latitude = 0.6784720829848033, Altitude = -1852.2084286233435, @@ -543,7 +544,7 @@ local keyframes = { }, ["1969-07-20T20:14:46"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.524906401275462, Latitude = 0.6784174518581257, Altitude = -1855.7490077854247, @@ -551,7 +552,7 @@ local keyframes = { }, ["1969-07-20T20:14:47"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.52349915098792, Latitude = 0.6782893729810321, Altitude = -1857.383121244847, @@ -559,7 +560,7 @@ local keyframes = { }, ["1969-07-20T20:14:48"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.522315823805602, Latitude = 0.6780556991046269, Altitude = -1859.5619391907433, @@ -567,7 +568,7 @@ local keyframes = { }, ["1969-07-20T20:14:49"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.52101739233993, Latitude = 0.6779647310824661, Altitude = -1862.2854616231134, @@ -575,7 +576,7 @@ local keyframes = { }, ["1969-07-20T20:14:50"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.51994166433182, Latitude = 0.6778711676787862, Altitude = -1864.7366318122467, @@ -583,7 +584,7 @@ local keyframes = { }, ["1969-07-20T20:14:51"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.51898851685442, Latitude = 0.6778817565177891, Altitude = -1866.643097514906, @@ -591,7 +592,7 @@ local keyframes = { }, ["1969-07-20T20:14:52"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.51808183367586, Latitude = 0.6778718533214779, Altitude = -1868.821915460802, @@ -599,7 +600,7 @@ local keyframes = { }, ["1969-07-20T20:14:53"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.517315195124922, Latitude = 0.6777409244088132, Altitude = -1869.6389721905132, @@ -607,7 +608,7 @@ local keyframes = { }, ["1969-07-20T20:14:54"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.516423288093712, Latitude = 0.6776383502937863, Altitude = -1872.0901423796465, @@ -615,7 +616,7 @@ local keyframes = { }, ["1969-07-20T20:14:55"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.515618488386473, Latitude = 0.6775904175972421, Altitude = -1873.7242558390685, @@ -623,7 +624,7 @@ local keyframes = { }, ["1969-07-20T20:14:56"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.514931748492103, Latitude = 0.677451729714544, Altitude = -1875.0860170552537, @@ -631,7 +632,7 @@ local keyframes = { }, ["1969-07-20T20:14:57"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.5141592094038, Latitude = 0.6774090469390076, Altitude = -1876.1754260282019, @@ -639,7 +640,7 @@ local keyframes = { }, ["1969-07-20T20:14:58"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.513268517407862, Latitude = 0.677380792748438, Altitude = -1878.3542439740982, @@ -647,7 +648,7 @@ local keyframes = { }, ["1969-07-20T20:14:59"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.51249864236425, Latitude = 0.6773301671802587, Altitude = -1878.8989484605722, @@ -655,7 +656,7 @@ local keyframes = { }, ["1969-07-20T20:15:00"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.511670817073732, Latitude = 0.6773498341149018, Altitude = -1879.9883574335202, @@ -663,7 +664,7 @@ local keyframes = { }, ["1969-07-20T20:15:01"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.510927468201952, Latitude = 0.6773124695718212, Altitude = -1881.0777664064683, @@ -671,7 +672,7 @@ local keyframes = { }, ["1969-07-20T20:15:02"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.510140364179833, Latitude = 0.6772452153026853, Altitude = -1882.9842321091276, @@ -679,7 +680,7 @@ local keyframes = { }, ["1969-07-20T20:15:03"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.50940612514804, Latitude = 0.6772084204274821, Altitude = -1884.3459933253127, @@ -687,7 +688,7 @@ local keyframes = { }, ["1969-07-20T20:15:04"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.508556629045042, Latitude = 0.6771417022964165, Altitude = -1885.1630500550239, @@ -695,7 +696,7 @@ local keyframes = { }, ["1969-07-20T20:15:05"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.5078270022667, Latitude = 0.6770996409435569, Altitude = -1885.707754541498, @@ -703,7 +704,7 @@ local keyframes = { }, ["1969-07-20T20:15:06"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.50712374883535, Latitude = 0.6770942256987497, Altitude = -1886.7971635144459, @@ -711,7 +712,7 @@ local keyframes = { }, ["1969-07-20T20:15:07"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.50638631083077, Latitude = 0.6770208020089364, Altitude = -1888.158924730631, @@ -719,7 +720,7 @@ local keyframes = { }, ["1969-07-20T20:15:08"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.50572166907488, Latitude = 0.6769421116864789, Altitude = -1888.431276973868, @@ -727,7 +728,7 @@ local keyframes = { }, ["1969-07-20T20:15:09"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.505080467779102, Latitude = 0.6769068207439769, Altitude = -1889.5206859468162, @@ -735,7 +736,7 @@ local keyframes = { }, ["1969-07-20T20:15:10"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.504394828536693, Latitude = 0.6768437996516232, Altitude = -1890.6100949197644, @@ -743,7 +744,7 @@ local keyframes = { }, ["1969-07-20T20:15:11"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.50370057106609, Latitude = 0.6767452474349132, Altitude = -1891.9718561359496, @@ -751,7 +752,7 @@ local keyframes = { }, ["1969-07-20T20:15:12"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.503056349392182, Latitude = 0.6766723806693259, Altitude = -1893.3336173521345, @@ -759,7 +760,7 @@ local keyframes = { }, ["1969-07-20T20:15:13"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.50246925266341, Latitude = 0.6766252349202276, Altitude = -1893.8783218386086, @@ -767,7 +768,7 @@ local keyframes = { }, ["1969-07-20T20:15:14"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.50184956306549, Latitude = 0.6765535257068991, Altitude = -1894.9677308115567, @@ -775,7 +776,7 @@ local keyframes = { }, ["1969-07-20T20:15:15"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.501422630419572, Latitude = 0.6765112802947014, Altitude = -1894.1506740818456, @@ -783,7 +784,7 @@ local keyframes = { }, ["1969-07-20T20:15:16"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.50104221348722, Latitude = 0.676487362071662, Altitude = -1893.8783218386086, @@ -791,7 +792,7 @@ local keyframes = { }, ["1969-07-20T20:15:17"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.50076948252455, Latitude = 0.6764658967447386, Altitude = -1892.2442083791866, @@ -799,7 +800,7 @@ local keyframes = { }, ["1969-07-20T20:15:18"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.50013364513089, Latitude = 0.6764482060496164, Altitude = -1893.3336173521345, @@ -807,7 +808,7 @@ local keyframes = { }, ["1969-07-20T20:15:19"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.499460285339502, Latitude = 0.6764309028737, Altitude = -1894.9677308115567, @@ -815,7 +816,7 @@ local keyframes = { }, ["1969-07-20T20:15:20"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.498899330647752, Latitude = 0.6763755753041285, Altitude = -1896.057139784505, @@ -823,7 +824,7 @@ local keyframes = { }, ["1969-07-20T20:15:21"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.49826864115494, Latitude = 0.6763489810183512, Altitude = -1896.601844270979, @@ -831,7 +832,7 @@ local keyframes = { }, ["1969-07-20T20:15:22"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.49765193973772, Latitude = 0.6763177659437667, Altitude = -1897.41890100069, @@ -839,7 +840,7 @@ local keyframes = { }, ["1969-07-20T20:15:23"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.49706547748806, Latitude = 0.6762368192356724, Altitude = -1898.2359577304012, @@ -847,7 +848,7 @@ local keyframes = { }, ["1969-07-20T20:15:24"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.496489420526313, Latitude = 0.676209886695223, Altitude = -1899.053014460112, @@ -855,7 +856,7 @@ local keyframes = { }, ["1969-07-20T20:15:25"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.495878153012562, Latitude = 0.6761763249034947, Altitude = -1900.1424234330602, @@ -863,7 +864,7 @@ local keyframes = { }, ["1969-07-20T20:15:26"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.4953425244022, Latitude = 0.6761311089575274, Altitude = -1901.5041846492454, @@ -871,7 +872,7 @@ local keyframes = { }, ["1969-07-20T20:15:27"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.494725217962213, Latitude = 0.6761017566851846, Altitude = -1902.5935936221936, @@ -879,7 +880,7 @@ local keyframes = { }, ["1969-07-20T20:15:28"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.494112443564592, Latitude = 0.6760842983575135, Altitude = -1903.4106503519047, @@ -887,7 +888,7 @@ local keyframes = { }, ["1969-07-20T20:15:29"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.493537644480202, Latitude = 0.6760386448926926, Altitude = -1903.9553548383788, @@ -895,7 +896,7 @@ local keyframes = { }, ["1969-07-20T20:15:30"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.49299719757025, Latitude = 0.6760147528943234, Altitude = -1903.9553548383788, @@ -903,7 +904,7 @@ local keyframes = { }, ["1969-07-20T20:15:31"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.492415313069813, Latitude = 0.6759919962423392, Altitude = -1904.2277070816158, @@ -911,7 +912,7 @@ local keyframes = { }, ["1969-07-20T20:15:32"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.491877755110142, Latitude = 0.6759640721591937, Altitude = -1904.2277070816158, @@ -919,7 +920,7 @@ local keyframes = { }, ["1969-07-20T20:15:33"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.49128819308786, Latitude = 0.6759491077295323, Altitude = -1904.2277070816158, @@ -927,7 +928,7 @@ local keyframes = { }, ["1969-07-20T20:15:34"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.49073158429634, Latitude = 0.6759379383686839, Altitude = -1904.2277070816158, @@ -935,7 +936,7 @@ local keyframes = { }, ["1969-07-20T20:15:35"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.490174891596332, Latitude = 0.6759054634588104, Altitude = -1904.2277070816158, @@ -943,7 +944,7 @@ local keyframes = { }, ["1969-07-20T20:15:36"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.489635065407523, Latitude = 0.6758939648884956, Altitude = -1904.5000593248528, @@ -951,7 +952,7 @@ local keyframes = { }, ["1969-07-20T20:15:37"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.4891060535486, Latitude = 0.6759004097281942, Altitude = -1904.2277070816158, @@ -959,7 +960,7 @@ local keyframes = { }, ["1969-07-20T20:15:38"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.48855436619652, Latitude = 0.6758862600165565, Altitude = -1904.2277070816158, @@ -967,7 +968,7 @@ local keyframes = { }, ["1969-07-20T20:15:39"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.488052711552413, Latitude = 0.6758544116957282, Altitude = -1904.5000593248528, @@ -975,7 +976,7 @@ local keyframes = { }, ["1969-07-20T20:15:40"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.48754943516269, Latitude = 0.6758316193430558, Altitude = -1904.2277070816158, @@ -983,7 +984,7 @@ local keyframes = { }, ["1969-07-20T20:15:41"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.487094304824993, Latitude = 0.6758175052522961, Altitude = -1904.2277070816158, @@ -991,7 +992,7 @@ local keyframes = { }, ["1969-07-20T20:15:42"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.486618165034592, Latitude = 0.6757757367756437, Altitude = -1904.7724115680899, @@ -999,7 +1000,7 @@ local keyframes = { }, ["1969-07-20T20:15:43"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.48604740534131, Latitude = 0.675733428263931, Altitude = -1905.3171160545637, @@ -1007,7 +1008,7 @@ local keyframes = { }, ["1969-07-20T20:15:44"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.48548248435554, Latitude = 0.6756797157749009, Altitude = -1905.8618205410378, @@ -1015,7 +1016,7 @@ local keyframes = { }, ["1969-07-20T20:15:45"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.48494957486896, Latitude = 0.6756120527881188, Altitude = -1905.8618205410378, @@ -1023,7 +1024,7 @@ local keyframes = { }, ["1969-07-20T20:15:46"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.484598386683622, Latitude = 0.675584857481579, Altitude = -1907.49593400046, @@ -1031,7 +1032,7 @@ local keyframes = { }, ["1969-07-20T20:15:47"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.4841269963268, Latitude = 0.6755482784409179, Altitude = -1908.040638486934, @@ -1039,7 +1040,7 @@ local keyframes = { }, ["1969-07-20T20:15:48"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.48373390336955, Latitude = 0.6754890811171497, Altitude = -1908.8576952166452, @@ -1047,7 +1048,7 @@ local keyframes = { }, ["1969-07-20T20:15:49"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.48325134882829, Latitude = 0.6754258626149947, Altitude = -1908.4491668517896, @@ -1055,7 +1056,7 @@ local keyframes = { }, ["1969-07-20T20:15:50"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.48284574619883, Latitude = 0.6753753196460469, Altitude = -1909.1300474598822, @@ -1063,7 +1064,7 @@ local keyframes = { }, ["1969-07-20T20:15:51"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.48245362823393, Latitude = 0.6753264776464533, Altitude = -1909.4023997031193, @@ -1071,7 +1072,7 @@ local keyframes = { }, ["1969-07-20T20:15:52"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.482060114185842, Latitude = 0.6752749804130574, Altitude = -1909.6747519463563, @@ -1079,7 +1080,7 @@ local keyframes = { }, ["1969-07-20T20:15:53"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.481698202127482, Latitude = 0.675223605520775, Altitude = -1909.6747519463563, @@ -1087,7 +1088,7 @@ local keyframes = { }, ["1969-07-20T20:15:54"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.48129046365451, Latitude = 0.6751730022703166, Altitude = -1909.6747519463563, @@ -1095,7 +1096,7 @@ local keyframes = { }, ["1969-07-20T20:15:55"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.480893026154902, Latitude = 0.6751376710849429, Altitude = -1909.6747519463563, @@ -1103,7 +1104,7 @@ local keyframes = { }, ["1969-07-20T20:15:56"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.48059324160945, Latitude = 0.6750772226256051, Altitude = -1909.6747519463563, @@ -1111,7 +1112,7 @@ local keyframes = { }, ["1969-07-20T20:15:57"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.48034984354739, Latitude = 0.6750430267458865, Altitude = -1909.6747519463563, @@ -1119,7 +1120,7 @@ local keyframes = { }, ["1969-07-20T20:15:58"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.48005268645993, Latitude = 0.6750019848756621, Altitude = -1909.6747519463563, @@ -1127,7 +1128,7 @@ local keyframes = { }, ["1969-07-20T20:15:59"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47978070153665, Latitude = 0.6749655364121049, Altitude = -1909.9471041895933, @@ -1135,7 +1136,7 @@ local keyframes = { }, ["1969-07-20T20:16:00"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47951311851127, Latitude = 0.6749420304945992, Altitude = -1909.9471041895933, @@ -1143,7 +1144,7 @@ local keyframes = { }, ["1969-07-20T20:16:01"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47927978098579, Latitude = 0.6748989409040068, Altitude = -1909.9471041895933, @@ -1151,7 +1152,7 @@ local keyframes = { }, ["1969-07-20T20:16:02"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47904250519933, Latitude = 0.6748472712728636, Altitude = -1910.4918086760674, @@ -1159,7 +1160,7 @@ local keyframes = { }, ["1969-07-20T20:16:03"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47879202998348, Latitude = 0.674809514541568, Altitude = -1910.7641609193045, @@ -1167,7 +1168,7 @@ local keyframes = { }, ["1969-07-20T20:16:04"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.478567222437622, Latitude = 0.6747692774477394, Altitude = -1910.7641609193045, @@ -1175,7 +1176,7 @@ local keyframes = { }, ["1969-07-20T20:16:05"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47836548542964, Latitude = 0.6747160116119115, Altitude = -1910.7641609193045, @@ -1183,7 +1184,7 @@ local keyframes = { }, ["1969-07-20T20:16:06"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47818769774975, Latitude = 0.6746866473279819, Altitude = -1911.3088654057785, @@ -1191,7 +1192,7 @@ local keyframes = { }, ["1969-07-20T20:16:07"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.477896613823983, Latitude = 0.6746547793250971, Altitude = -1913.2153311084376, @@ -1199,7 +1200,7 @@ local keyframes = { }, ["1969-07-20T20:16:08"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47781195503974, Latitude = 0.6746276583132307, Altitude = -1913.2153311084376, @@ -1207,7 +1208,7 @@ local keyframes = { }, ["1969-07-20T20:16:09"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.477664452707373, Latitude = 0.6746112868414526, Altitude = -1914.0323878381487, @@ -1215,7 +1216,7 @@ local keyframes = { }, -- ["1969-07-20T20:16:10"] = { -- Type = "GlobeTranslation", - -- Globe = "Moon", + -- Globe = moon.Moon.Identifier, -- Longitude = 23.477750217762413, -- Latitude = 0.6745910947360472, -- Altitude = -1912.6706266219635, @@ -1223,7 +1224,7 @@ local keyframes = { -- }, -- ["1969-07-20T20:16:11"] = { -- Type = "GlobeTranslation", - -- Globe = "Moon", + -- Globe = moon.Moon.Identifier, -- Longitude = 23.477590925415402, -- Latitude = 0.6745598993839581, -- Altitude = -1912.6706266219635, @@ -1231,7 +1232,7 @@ local keyframes = { -- }, -- ["1969-07-20T20:16:12"] = { -- Type = "GlobeTranslation", - -- Globe = "Moon", + -- Globe = moon.Moon.Identifier, -- Longitude = 23.47745952757753, -- Latitude = 0.6745298610932787, -- Altitude = -1912.6706266219635, @@ -1239,7 +1240,7 @@ local keyframes = { -- }, -- ["1969-07-20T20:16:13"] = { -- Type = "GlobeTranslation", - -- Globe = "Moon", + -- Globe = moon.Moon.Identifier, -- Longitude = 23.477271343369093, -- Latitude = 0.6745166392893209, -- Altitude = -1913.2153311084376, @@ -1247,7 +1248,7 @@ local keyframes = { -- }, -- ["1969-07-20T20:16:14"] = { -- Type = "GlobeTranslation", - -- Globe = "Moon", + -- Globe = moon.Moon.Identifier, -- Longitude = 23.477100932665042, -- Latitude = 0.6744937499451563, -- Altitude = -1914.3047400813857, @@ -1255,7 +1256,7 @@ local keyframes = { -- }, ["1969-07-20T20:16:15"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47697690593997, Latitude = 0.6744644602883288, Altitude = -1914.8494445678598, @@ -1263,7 +1264,7 @@ local keyframes = { }, ["1969-07-20T20:16:16"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.476842953277412, Latitude = 0.6744457159538018, Altitude = -1915.1217968110968, @@ -1271,7 +1272,7 @@ local keyframes = { }, ["1969-07-20T20:16:17"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.476774052091812, Latitude = 0.6744243634139203, Altitude = -1914.8494445678598, @@ -1279,7 +1280,7 @@ local keyframes = { }, ["1969-07-20T20:16:18"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47665204889191, Latitude = 0.6743981221140924, Altitude = -1915.1217968110968, @@ -1287,7 +1288,7 @@ local keyframes = { }, ["1969-07-20T20:16:19"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47657652039885, Latitude = 0.6743808573601865, Altitude = -1915.1217968110968, @@ -1295,7 +1296,7 @@ local keyframes = { }, ["1969-07-20T20:16:20"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.476475036022492, Latitude = 0.6743552389834175, Altitude = -1914.8494445678598, @@ -1303,7 +1304,7 @@ local keyframes = { }, ["1969-07-20T20:16:21"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47638671770867, Latitude = 0.6743412077411113, Altitude = -1915.3941490543339, @@ -1311,7 +1312,7 @@ local keyframes = { }, ["1969-07-20T20:16:22"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.476286834646782, Latitude = 0.6743241644041175, Altitude = -1915.3941490543339, @@ -1319,7 +1320,7 @@ local keyframes = { }, ["1969-07-20T20:16:23"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47623840477727, Latitude = 0.6743121023448013, Altitude = -1915.3941490543339, @@ -1327,7 +1328,7 @@ local keyframes = { }, ["1969-07-20T20:16:24"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.476125794037742, Latitude = 0.6743019779643423, Altitude = -1915.938853540808, @@ -1335,7 +1336,7 @@ local keyframes = { }, ["1969-07-20T20:16:25"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47604582826371, Latitude = 0.6742984062330349, Altitude = -1916.211205784045, @@ -1343,7 +1344,7 @@ local keyframes = { }, ["1969-07-20T20:16:26"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47599605084473, Latitude = 0.6742864748966985, Altitude = -1916.211205784045, @@ -1351,7 +1352,7 @@ local keyframes = { }, ["1969-07-20T20:16:27"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47598166921822, Latitude = 0.6742856341308172, Altitude = -1916.755910270519, @@ -1359,7 +1360,7 @@ local keyframes = { }, -- ["1969-07-20T20:16:28"] = { -- Type = "GlobeTranslation", - -- Globe = "Moon", + -- Globe = moon.Moon.Identifier, -- Longitude = 23.47600003592791, -- Latitude = 0.6742816108377042, -- Altitude = -1916.211205784045, @@ -1367,7 +1368,7 @@ local keyframes = { -- }, -- ["1969-07-20T20:16:29"] = { -- Type = "GlobeTranslation", - -- Globe = "Moon", + -- Globe = moon.Moon.Identifier, -- Longitude = 23.47593990066764, -- Latitude = 0.6742699316275284, -- Altitude = -1916.483558027282, @@ -1375,7 +1376,7 @@ local keyframes = { -- }, ["1969-07-20T20:16:30"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47587957412098, Latitude = 0.6742661771136219, Altitude = -1916.755910270519, @@ -1383,7 +1384,7 @@ local keyframes = { }, ["1969-07-20T20:16:31"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47579282136856, Latitude = 0.6742214263433656, Altitude = -1917.028262513756, @@ -1391,7 +1392,7 @@ local keyframes = { }, ["1969-07-20T20:16:32"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47571834266516, Latitude = 0.6741885448706321, Altitude = -1917.5729670002302, @@ -1399,7 +1400,7 @@ local keyframes = { }, -- ["1969-07-20T20:16:33"] = { -- Type = "GlobeTranslation", - -- Globe = "Moon", + -- Globe = moon.Moon.Identifier, -- Longitude = 23.47569457676149, -- Latitude = 0.6741859152655852, -- Altitude = -1917.3006147569931, @@ -1407,7 +1408,7 @@ local keyframes = { -- }, ["1969-07-20T20:16:34"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47557041293751, Latitude = 0.6741798073326593, Altitude = -1918.117671486704, @@ -1415,7 +1416,7 @@ local keyframes = { }, ["1969-07-20T20:16:35"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.475475681892203, Latitude = 0.6741822414281841, Altitude = -1918.117671486704, @@ -1423,7 +1424,7 @@ local keyframes = { }, ["1969-07-20T20:16:36"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47541533097675, Latitude = 0.6742009046793005, Altitude = -1918.390023729941, @@ -1431,7 +1432,7 @@ local keyframes = { }, ["1969-07-20T20:16:37"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47532207549478, Latitude = 0.6742269926054295, Altitude = -1918.662375973178, @@ -1439,7 +1440,7 @@ local keyframes = { }, ["1969-07-20T20:16:38"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47522251798864, Latitude = 0.6742695236577596, Altitude = -1918.662375973178, @@ -1447,7 +1448,7 @@ local keyframes = { }, ["1969-07-20T20:16:39"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47513564425997, Latitude = 0.6742809051574165, Altitude = -1918.662375973178, @@ -1455,7 +1456,7 @@ local keyframes = { }, ["1969-07-20T20:16:40"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47498810518855, Latitude = 0.6743095342428154, Altitude = -1920.2964894326003, @@ -1463,7 +1464,7 @@ local keyframes = { }, -- ["1969-07-20T20:16:41"] = { -- Type = "GlobeTranslation", - -- Globe = "Moon", + -- Globe = moon.Moon.Identifier, -- Longitude = 23.47489523759891, -- Latitude = 0.6743154022599566, -- Altitude = -1920.0241371893633, @@ -1471,7 +1472,7 @@ local keyframes = { -- }, -- ["1969-07-20T20:16:42"] = { -- Type = "GlobeTranslation", - -- Globe = "Moon", + -- Globe = moon.Moon.Identifier, -- Longitude = 23.47479438729774, -- Latitude = 0.6743324078003049, -- Altitude = -1920.2964894326003, @@ -1479,7 +1480,7 @@ local keyframes = { -- }, -- ["1969-07-20T20:16:43"] = { -- Type = "GlobeTranslation", - -- Globe = "Moon", + -- Globe = moon.Moon.Identifier, -- Longitude = 23.47475788126512, -- Latitude = 0.674345583979325, -- Altitude = -1920.0241371893633, @@ -1487,7 +1488,7 @@ local keyframes = { -- }, ["1969-07-20T20:16:44"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.474678823712882, Latitude = 0.6743691203511213, Altitude = -1920.2964894326003, @@ -1495,7 +1496,7 @@ local keyframes = { }, ["1969-07-20T20:16:45"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47460302474115, Latitude = 0.6743890347121807, Altitude = -1920.2964894326003, @@ -1503,7 +1504,7 @@ local keyframes = { }, ["1969-07-20T20:16:46"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47450130965027, Latitude = 0.6744202280781089, Altitude = -1920.8411939190744, @@ -1511,7 +1512,7 @@ local keyframes = { }, ["1969-07-20T20:16:47"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.474379586340042, Latitude = 0.6744490653475903, Altitude = -1921.1135461623114, @@ -1519,7 +1520,7 @@ local keyframes = { }, ["1969-07-20T20:16:48"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47431921657337, Latitude = 0.6745028925523043, Altitude = -1921.1135461623114, @@ -1527,7 +1528,7 @@ local keyframes = { }, ["1969-07-20T20:16:49"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47424698504895, Latitude = 0.6745115395661241, Altitude = -1921.1135461623114, @@ -1535,7 +1536,7 @@ local keyframes = { }, ["1969-07-20T20:16:50"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.474158028620153, Latitude = 0.6745268900936557, Altitude = -1921.6582506487855, @@ -1543,7 +1544,7 @@ local keyframes = { }, ["1969-07-20T20:16:51"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47408003386958, Latitude = 0.674531434078838, Altitude = -1921.6582506487855, @@ -1551,7 +1552,7 @@ local keyframes = { }, ["1969-07-20T20:16:52"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.473993195514502, Latitude = 0.6745434127092755, Altitude = -1921.9306028920225, @@ -1559,7 +1560,7 @@ local keyframes = { }, -- ["1969-07-20T20:16:53"] = { -- Type = "GlobeTranslation", - -- Globe = "Moon", + -- Globe = moon.Moon.Identifier, -- Longitude = 23.47392353665608, -- Latitude = 0.6745464032805983, -- Altitude = -1922.2029551352596, @@ -1567,7 +1568,7 @@ local keyframes = { -- }, ["1969-07-20T20:16:54"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47388537487237, Latitude = 0.674552865152663, Altitude = -1921.9306028920225, @@ -1575,7 +1576,7 @@ local keyframes = { }, ["1969-07-20T20:16:55"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47382957912373, Latitude = 0.6745443566727537, Altitude = -1921.9306028920225, @@ -1583,7 +1584,7 @@ local keyframes = { }, ["1969-07-20T20:16:56"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47378652829031, Latitude = 0.6745361955127924, Altitude = -1921.6582506487855, @@ -1591,7 +1592,7 @@ local keyframes = { }, ["1969-07-20T20:16:57"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.473741159081282, Latitude = 0.6745139398577651, Altitude = -1921.6582506487855, @@ -1599,7 +1600,7 @@ local keyframes = { }, ["1969-07-20T20:16:58"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.473674434325403, Latitude = 0.6745046665169872, Altitude = -1922.2029551352596, @@ -1607,7 +1608,7 @@ local keyframes = { }, ["1969-07-20T20:16:59"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47366202033169, Latitude = 0.6744553774680945, Altitude = -1922.2029551352596, @@ -1615,7 +1616,7 @@ local keyframes = { }, ["1969-07-20T20:17:00"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47360771579434, Latitude = 0.6744345598586292, Altitude = -1922.7476596217336, @@ -1623,7 +1624,7 @@ local keyframes = { }, ["1969-07-20T20:17:01"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47357090816817, Latitude = 0.6744054827778567, Altitude = -1923.0200118649707, @@ -1631,7 +1632,7 @@ local keyframes = { }, ["1969-07-20T20:17:02"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47354290217646, Latitude = 0.6743765403194303, Altitude = -1923.2923641082077, @@ -1639,7 +1640,7 @@ local keyframes = { }, ["1969-07-20T20:17:03"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47354640286736, Latitude = 0.6743332580785223, Altitude = -1923.5647163514448, @@ -1647,7 +1648,7 @@ local keyframes = { }, ["1969-07-20T20:17:04"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.473541367503802, Latitude = 0.6742974556070759, Altitude = -1923.8370685946818, @@ -1655,7 +1656,7 @@ local keyframes = { }, ["1969-07-20T20:17:05"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47350854369485, Latitude = 0.6742858449512636, Altitude = -1924.1094208379188, @@ -1663,7 +1664,7 @@ local keyframes = { }, ["1969-07-20T20:17:06"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47347424911663, Latitude = 0.6742611487873781, Altitude = -1924.6541253243927, @@ -1671,7 +1672,7 @@ local keyframes = { }, ["1969-07-20T20:17:07"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.473503629496022, Latitude = 0.6742462694505276, Altitude = -1924.6541253243927, @@ -1679,7 +1680,7 @@ local keyframes = { }, ["1969-07-20T20:17:08"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.473512768546712, Latitude = 0.6742384048959066, Altitude = -1924.6541253243927, @@ -1687,7 +1688,7 @@ local keyframes = { }, ["1969-07-20T20:17:09"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47353343175876, Latitude = 0.6742241072273591, Altitude = -1924.3817730811559, @@ -1695,7 +1696,7 @@ local keyframes = { }, ["1969-07-20T20:17:10"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47353316391657, Latitude = 0.6742142580747189, Altitude = -1925.4711820541038, @@ -1703,7 +1704,7 @@ local keyframes = { }, ["1969-07-20T20:17:11"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47355774790429, Latitude = 0.6742015107317392, Altitude = -1924.9264775676297, @@ -1711,7 +1712,7 @@ local keyframes = { }, ["1969-07-20T20:17:12"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.4735540335665, Latitude = 0.6741800864866416, Altitude = -1924.9264775676297, @@ -1719,7 +1720,7 @@ local keyframes = { }, ["1969-07-20T20:17:13"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47353500681606, Latitude = 0.6741617950501063, Altitude = -1925.1988298108668, @@ -1727,7 +1728,7 @@ local keyframes = { }, ["1969-07-20T20:17:14"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47350664772458, Latitude = 0.6741447111551033, Altitude = -1925.4711820541038, @@ -1735,7 +1736,7 @@ local keyframes = { }, ["1969-07-20T20:17:15"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.473494757982273, Latitude = 0.6741430011390509, Altitude = -1925.4711820541038, @@ -1743,7 +1744,7 @@ local keyframes = { }, ["1969-07-20T20:17:16"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.473485349949943, Latitude = 0.6741431504511513, Altitude = -1925.4711820541038, @@ -1751,7 +1752,7 @@ local keyframes = { }, ["1969-07-20T20:17:17"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.473464448566723, Latitude = 0.674141681840806, Altitude = -1925.4711820541038, @@ -1759,7 +1760,7 @@ local keyframes = { }, ["1969-07-20T20:17:18"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47344203973089, Latitude = 0.6741518055278933, Altitude = -1925.4711820541038, @@ -1767,7 +1768,7 @@ local keyframes = { }, ["1969-07-20T20:17:19"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.473416197134252, Latitude = 0.6741705280217748, Altitude = -1925.7435342973408, @@ -1775,7 +1776,7 @@ local keyframes = { }, ["1969-07-20T20:17:20"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47339416150648, Latitude = 0.6741799656622618, Altitude = -1925.7435342973408, @@ -1783,7 +1784,7 @@ local keyframes = { }, ["1969-07-20T20:17:21"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.4733232813815, Latitude = 0.6741727841821631, Altitude = -1926.288238783815, @@ -1791,7 +1792,7 @@ local keyframes = { }, ["1969-07-20T20:17:24"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47324174890097, Latitude = 0.6742091863213222, Altitude = -1926.288238783815, @@ -1799,7 +1800,7 @@ local keyframes = { }, ["1969-07-20T20:17:27"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47317556908458, Latitude = 0.6742072669430229, Altitude = -1926.560591027052, @@ -1807,7 +1808,7 @@ local keyframes = { }, ["1969-07-20T20:17:30"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47310752310149, Latitude = 0.6742134078571678, Altitude = -1926.832943270289, @@ -1815,7 +1816,7 @@ local keyframes = { }, ["1969-07-20T20:17:32"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.473074792306253, Latitude = 0.6741925230045956, Altitude = -1927.105295513526, @@ -1823,7 +1824,7 @@ local keyframes = { }, ["1969-07-20T20:17:40"] = { Type = "GlobeTranslation", - Globe = "Moon", + Globe = moon.Moon.Identifier, Longitude = 23.47306, Latitude = 0.67402, Altitude = -1927.65, @@ -1832,3 +1833,14 @@ local keyframes = { } asset.export("keyframes", keyframes) + + + +asset.meta = { + Name = "Apollo 11 Descent Position", + Description = [[This asset provides position information about Apollo 11 as it is in the + final stages of the descent onto the Moon.]], + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/scene/solarsystem/missions/apollo/11/lem_descent_rotation.asset b/data/assets/scene/solarsystem/missions/apollo/11/lem_descent_rotation.asset index 3b06445857..b01fa75349 100644 --- a/data/assets/scene/solarsystem/missions/apollo/11/lem_descent_rotation.asset +++ b/data/assets/scene/solarsystem/missions/apollo/11/lem_descent_rotation.asset @@ -1,4 +1,4 @@ -asset.export("keyframes", { +local keyframes = { -- ["1969-7-20T20:9:53"] = { -- Type = "StaticRotation", -- Rotation = { -1.3815, -0.0048, -0.4891 } @@ -1583,4 +1583,17 @@ asset.export("keyframes", { Type = "StaticRotation", Rotation = { -0.0794, -0.0088, -0.2447 } } -}) +} + +asset.export("keyframes", keyframes) + + + +asset.meta = { + Name = "Apollo 11 Descent Orientation", + Description = [[This asset provides orientation information about Apollo 11 as it is in + the final stages of the descent onto the Moon.]], + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/scene/solarsystem/missions/apollo/11/lem_flipbook.asset b/data/assets/scene/solarsystem/missions/apollo/11/lem_flipbook.asset index bedc3c2b69..07b8fa824b 100644 --- a/data/assets/scene/solarsystem/missions/apollo/11/lem_flipbook.asset +++ b/data/assets/scene/solarsystem/missions/apollo/11/lem_flipbook.asset @@ -1,10 +1,10 @@ local helper = asset.require("util/vrt_flipbook_helper") -local moonAsset = asset.require("scene/solarsystem/planets/earth/moon/moon") +local moon = asset.require("scene/solarsystem/planets/earth/moon/moon") local assetPrefix = "A11flip" -local assetGlobe = moonAsset.Moon.Identifier +local assetGlobe = moon.Moon.Identifier local flipbookCount = 19 local flipbook = nil @@ -48,3 +48,14 @@ asset.onDeinitialize(function() openspace.action.removeAction("os.lemFlipbook.NextFlip") openspace.action.removeAction("os.lemFlipbook.PrevFlip") end) + + + +asset.meta = { + Name = "Apollo 11 Landing Site Flipbook", + Description = [[This asset provides georeferenced images of the Apollo 11 landing site, + taken with different illumination angles.]], + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/scene/solarsystem/missions/apollo/15/apollo15.asset b/data/assets/scene/solarsystem/missions/apollo/15/apollo15.asset index 233a597e03..df6a113a29 100644 --- a/data/assets/scene/solarsystem/missions/apollo/15/apollo15.asset +++ b/data/assets/scene/solarsystem/missions/apollo/15/apollo15.asset @@ -1,5 +1,5 @@ asset.require("../actions") -local moonTransforms = asset.require("scene/solarsystem/planets/earth/moon/moon") +local moon = asset.require("scene/solarsystem/planets/earth/moon/moon") local sun = asset.require("scene/solarsystem/sun/transforms") local kernels = asset.require("./kernels") local coreKernels = asset.require("spice/core") @@ -16,7 +16,7 @@ local models = asset.resource({ local Apollo15 = { Identifier = "Apollo15", - Parent = moonTransforms.Moon.Identifier, + Parent = moon.Moon.Identifier, TimeFrame = { Type = "TimeFrameInterval", Start = "1971-07-30T02:22:00.00", @@ -52,7 +52,7 @@ local Apollo15 = { local Apollo15Trail = { Identifier = "Apollo15Trail", - Parent = moonTransforms.Moon.Identifier, + Parent = moon.Moon.Identifier, Renderable = { Type = "RenderableTrailTrajectory", Translation = { @@ -68,7 +68,8 @@ local Apollo15Trail = { }, GUI = { Name = "Apollo 15 Trail", - Path = "/Solar System/Missions/Apollo/15" + Path = "/Solar System/Missions/Apollo/15", + Focusable = false } } @@ -85,3 +86,14 @@ end) asset.export(Apollo15) asset.export(Apollo15Trail) + + + +asset.meta = { + Name = "Apollo 15", + Description = [[This asset provides a 3D model and a Moon-centered trail of the Apollo + 15 command and service module.]], + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/scene/solarsystem/missions/apollo/15/kernels.asset b/data/assets/scene/solarsystem/missions/apollo/15/kernels.asset index 6b092ae8f9..1f870f87fd 100644 --- a/data/assets/scene/solarsystem/missions/apollo/15/kernels.asset +++ b/data/assets/scene/solarsystem/missions/apollo/15/kernels.asset @@ -35,3 +35,14 @@ end) asset.export("ID", ID) asset.export("Frame", Frame) + + + +asset.meta = { + Name = "Apollo 15 Kernels", + Description = [[This asset provides the SPICE kernels for the Apollo 15 module that + provide position and orientation information for the mission.]], + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/scene/solarsystem/missions/apollo/17/apollo17.asset b/data/assets/scene/solarsystem/missions/apollo/17/apollo17.asset index dc40e224af..694b9f16c5 100644 --- a/data/assets/scene/solarsystem/missions/apollo/17/apollo17.asset +++ b/data/assets/scene/solarsystem/missions/apollo/17/apollo17.asset @@ -1,3 +1,14 @@ asset.require("./lem") asset.require("./actions") asset.require("../actions") + + + +asset.meta = { + Name = "Apollo 17", + Description = [[A meta asset that will include all of the other assets to show the + Apollo 17 launch, orbit, and landing sequence.]], + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/scene/solarsystem/missions/apollo/17/bouldersstation2.asset b/data/assets/scene/solarsystem/missions/apollo/17/bouldersstation2.asset index 074b3dc905..86dced27e9 100644 --- a/data/assets/scene/solarsystem/missions/apollo/17/bouldersstation2.asset +++ b/data/assets/scene/solarsystem/missions/apollo/17/bouldersstation2.asset @@ -1,5 +1,5 @@ local sun = asset.require("scene/solarsystem/sun/transforms") -local moonAsset = asset.require("scene/solarsystem/planets/earth/moon/moon") +local moon = asset.require("scene/solarsystem/planets/earth/moon/moon") @@ -13,11 +13,11 @@ local models = asset.resource({ local Station2Boulder1Holder = { Identifier = "Station_2_Boulder1", - Parent = moonAsset.Moon.Identifier, + Parent = moon.Moon.Identifier, Transform = { Translation = { Type = "GlobeTranslation", - Globe = moonAsset.Moon.Identifier, + Globe = moon.Moon.Identifier, Longitude = -360 + 30.5294692, Latitude = 20.098824, Altitude = -2442.8, @@ -62,11 +62,11 @@ local Station2Boulder1Model = { local Station2Boulder2Holder = { Identifier = "Station_2_Boulder2", - Parent = moonAsset.Moon.Identifier, + Parent = moon.Moon.Identifier, Transform = { Translation = { Type = "GlobeTranslation", - Globe = moonAsset.Moon.Identifier, + Globe = moon.Moon.Identifier, Longitude = -360 + 30.5287892, Latitude = 20.098240, Altitude = -2434.6, @@ -111,11 +111,11 @@ local Station2Boulder2Model = { local Station2Boulder3Holder = { Identifier = "Station_2_Boulder3", - Parent = moonAsset.Moon.Identifier, + Parent = moon.Moon.Identifier, Transform = { Translation = { Type = "GlobeTranslation", - Globe = moonAsset.Moon.Identifier, + Globe = moon.Moon.Identifier, Longitude = -360 + 30.5294692, Latitude = 20.098610, Altitude = -2441.55, @@ -183,3 +183,14 @@ asset.export(Station2Boulder2Holder) asset.export(Station2Boulder2Model) asset.export(Station2Boulder3Holder) asset.export(Station2Boulder3Model) + + + +asset.meta = { + Name = "Apollo 17 - Boulder Station 2", + Description = [[This asset shows 3D models of the boulders at station 2, which have been + reconstructed from the imagery taken of the Apollo 17 crew.]], + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/scene/solarsystem/missions/apollo/17/bouldersstation6.asset b/data/assets/scene/solarsystem/missions/apollo/17/bouldersstation6.asset index 5cbe8f72f5..e4e0f4e00a 100644 --- a/data/assets/scene/solarsystem/missions/apollo/17/bouldersstation6.asset +++ b/data/assets/scene/solarsystem/missions/apollo/17/bouldersstation6.asset @@ -1,5 +1,5 @@ local sun = asset.require("scene/solarsystem/sun/transforms") -local moonAsset = asset.require("scene/solarsystem/planets/earth/moon/moon") +local moon = asset.require("scene/solarsystem/planets/earth/moon/moon") @@ -13,11 +13,11 @@ local models = asset.resource({ local Station6Frag1Holder = { Identifier = "Station_6_Fragment1", - Parent = moonAsset.Moon.Identifier, + Parent = moon.Moon.Identifier, Transform = { Translation = { Type = "GlobeTranslation", - Globe = moonAsset.Moon.Identifier, + Globe = moon.Moon.Identifier, Longitude = -360 + 30.80068, Latitude = 20.2903, Altitude = -2562.6, @@ -36,7 +36,7 @@ local Station6Frag1Model = { Transform = { Translation = { Type = "GlobeTranslation", - Globe = moonAsset.Moon.Identifier, + Globe = moon.Moon.Identifier, Longitude = -360 + 30.8007, Latitude = 20.2903, Altitude = -2562.6, @@ -70,7 +70,7 @@ local Station6Frag1Model = { local Station6Frag23Holder = { Identifier = "Station_6_Fragments_2_3", - Parent = moonAsset.Moon.Identifier, + Parent = moon.Moon.Identifier, GUI = { Name = "Station 6 Fragments 2 & 3 Holder", Path = "/Solar System/Missions/Apollo/17/Station 6" @@ -87,7 +87,7 @@ local Station6Frag2Model = { }, Translation = { Type = "GlobeTranslation", - Globe = moonAsset.Moon.Identifier, + Globe = moon.Moon.Identifier, Longitude = -360 + 30.80055, Latitude = 20.289808, Altitude = -2566.5, @@ -125,7 +125,7 @@ local Station6Frag3Model = { }, Translation = { Type = "GlobeTranslation", - Globe = moonAsset.Moon.Identifier, + Globe = moon.Moon.Identifier, Longitude = -360 + 30.80053, Latitude = 20.29030, Altitude = -2563.0, @@ -175,3 +175,14 @@ asset.export(Station6Frag1Model) asset.export(Station6Frag23Holder) asset.export(Station6Frag2Model) asset.export(Station6Frag3Model) + + + +asset.meta = { + Name = "Apollo 17 - Boulder Station 6", + Description = [[This asset shows 3D models of the fragments at station 6, which have + been reconstructed from the imagery taken of the Apollo 17 crew.]], + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/scene/solarsystem/missions/apollo/17/bouldersstation7.asset b/data/assets/scene/solarsystem/missions/apollo/17/bouldersstation7.asset index 9ddf9748e8..2c85eabfce 100644 --- a/data/assets/scene/solarsystem/missions/apollo/17/bouldersstation7.asset +++ b/data/assets/scene/solarsystem/missions/apollo/17/bouldersstation7.asset @@ -1,5 +1,5 @@ local sun = asset.require("scene/solarsystem/sun/transforms") -local moonAsset = asset.require("scene/solarsystem/planets/earth/moon/moon") +local moon = asset.require("scene/solarsystem/planets/earth/moon/moon") @@ -13,11 +13,11 @@ local models = asset.resource({ local Station7BoulderHolder = { Identifier = "Station_7_Boulder", - Parent = moonAsset.Moon.Identifier, + Parent = moon.Moon.Identifier, Transform = { Translation = { Type = "GlobeTranslation", - Globe = moonAsset.Moon.Identifier, + Globe = moon.Moon.Identifier, Longitude = -360 + 30.8165882, Latitude = 20.2908556, Altitude = -2593.5, @@ -73,3 +73,14 @@ end) asset.export(Station7BoulderHolder) asset.export(Station7BoulderModel) + + + +asset.meta = { + Name = "Apollo 17 - Boulder Station 7", + Description = [[This asset shows the 3D model of the boulder found at station 7, which + has been reconstructed from the imagery taken of the Apollo 17 crew.]], + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/scene/solarsystem/missions/apollo/17/lem.asset b/data/assets/scene/solarsystem/missions/apollo/17/lem.asset index de5d8b2bdf..a2bce9dd7f 100644 --- a/data/assets/scene/solarsystem/missions/apollo/17/lem.asset +++ b/data/assets/scene/solarsystem/missions/apollo/17/lem.asset @@ -1,5 +1,5 @@ local sun = asset.require("scene/solarsystem/sun/transforms") -local moonAsset = asset.require("scene/solarsystem/planets/earth/moon/moon") +local moon = asset.require("scene/solarsystem/planets/earth/moon/moon") @@ -13,18 +13,18 @@ local model = asset.resource({ local Apollo17Lem = { Identifier = "Apollo17Lem", - Parent = moonAsset.Moon.Identifier, + Parent = moon.Moon.Identifier, Transform = { Translation = { Type = "GlobeTranslation", - Globe = moonAsset.Moon.Identifier, + Globe = moon.Moon.Identifier, Longitude = 30.77167, Latitude = 20.19092, UseHeightmap = true }, Rotation = { Type = "GlobeRotation", - Globe = moonAsset.Moon.Identifier, + Globe = moon.Moon.Identifier, Longitude = 30.77167, Latitude = 20.19092 } @@ -78,3 +78,14 @@ end) asset.export(Apollo17Lem) asset.export(Apollo17LemModel) + + + +asset.meta = { + Name = "Apollo 17 Lunar Excursion Module", + Description = [[This asset provides a 3D model of the Apollo Lunar Module/Lunar + Excursion Module of Apollo 17.]], + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/scene/solarsystem/missions/apollo/8/apollo8.asset b/data/assets/scene/solarsystem/missions/apollo/8/apollo8.asset index 6f1d47d3bf..2976d968b1 100644 --- a/data/assets/scene/solarsystem/missions/apollo/8/apollo8.asset +++ b/data/assets/scene/solarsystem/missions/apollo/8/apollo8.asset @@ -3,3 +3,14 @@ asset.require("./launch_model") asset.require("./trails") asset.require("./actions") asset.require("../actions") + + + +asset.meta = { + Name = "Apollo 8", + Description = [[A meta asset that will include all of the other assets to show the + Apollo 8 launch and orbit trajectory]], + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/scene/solarsystem/missions/apollo/8/kernels.asset b/data/assets/scene/solarsystem/missions/apollo/8/kernels.asset index 1474dba208..2144283699 100644 --- a/data/assets/scene/solarsystem/missions/apollo/8/kernels.asset +++ b/data/assets/scene/solarsystem/missions/apollo/8/kernels.asset @@ -35,3 +35,14 @@ end) asset.export("ID", ID) asset.export("Frame", Frame) + + + +asset.meta = { + Name = "Apollo 8 Kernel", + Description = [[This asset downloads and provides the kernels needed for the Apollo 8 + launch and the orientation of the capsule during the Earthrise moment]], + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/scene/solarsystem/missions/apollo/8/launch_model.asset b/data/assets/scene/solarsystem/missions/apollo/8/launch_model.asset index b231d1ffb8..650ef9b555 100644 --- a/data/assets/scene/solarsystem/missions/apollo/8/launch_model.asset +++ b/data/assets/scene/solarsystem/missions/apollo/8/launch_model.asset @@ -80,3 +80,14 @@ end) asset.export(Apollo8Launch) asset.export(Apollo8LaunchModel) + + + +asset.meta = { + Name = "Apollo 8 Launch Model", + Description = [[Contains the 3D model of the Apollo 8 command module for use during the + launch of the spacecraft from Earth.]], + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/scene/solarsystem/missions/apollo/8/model.asset b/data/assets/scene/solarsystem/missions/apollo/8/model.asset index a4f89cff77..6955f16816 100644 --- a/data/assets/scene/solarsystem/missions/apollo/8/model.asset +++ b/data/assets/scene/solarsystem/missions/apollo/8/model.asset @@ -109,3 +109,14 @@ end) asset.export(Apollo8) asset.export(Apollo8Model) asset.export(Apollo8Pivot) + + + +asset.meta = { + Name = "Apollo 8 Model", + Description = [[Contains the 3D model of the Apollo 8 command module for use during the + launch of the spacecraft from Earth and the Earthrise moment.]], + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/scene/solarsystem/missions/apollo/8/trails.asset b/data/assets/scene/solarsystem/missions/apollo/8/trails.asset index baf3c51688..f6dff794ba 100644 --- a/data/assets/scene/solarsystem/missions/apollo/8/trails.asset +++ b/data/assets/scene/solarsystem/missions/apollo/8/trails.asset @@ -1,5 +1,5 @@ local earth_transforms = asset.require("scene/solarsystem/planets/earth/transforms") -local moon_transforms = asset.require("scene/solarsystem/planets/earth/moon/moon") +local moon = asset.require("scene/solarsystem/planets/earth/moon/moon") local kernels = asset.require("./kernels") local coreKernels = asset.require("spice/core") @@ -24,13 +24,14 @@ local LaunchTrail = { }, GUI = { Name = "Apollo 8 Launch Trail", - Path = "/Solar System/Missions/Apollo/8" + Path = "/Solar System/Missions/Apollo/8", + Focusable = false } } local MoonTrail = { Identifier = "Apollo8MoonTrail", - Parent = moon_transforms.Moon.Identifier, + Parent = moon.Moon.Identifier, Renderable = { Type = "RenderableTrailTrajectory", Enabled = false, @@ -47,7 +48,8 @@ local MoonTrail = { }, GUI = { Name = "Apollo 8 Moon Trail", - Path = "/Solar System/Missions/Apollo/8" + Path = "/Solar System/Missions/Apollo/8", + Focusable = false } } @@ -70,7 +72,8 @@ local EarthBarycenterTrail = { }, GUI = { Name = "Apollo 8 Earth Barycenter Trail", - Path = "/Solar System/Missions/Apollo/8" + Path = "/Solar System/Missions/Apollo/8", + Focusable = false } } @@ -90,3 +93,17 @@ end) asset.export(LaunchTrail) asset.export(MoonTrail) asset.export(EarthBarycenterTrail) + + + +asset.meta = { + Name = "Apollo 8 Trail", + Description = [[Provides three trails for the Apollo 8 capsule: A launch trail that + corotates with the Earth and is thus valid for the first few hours of the mission, + an Earth-based non-rotating trail that will better represent the trajectory of the + capsule after the trans-lunar injection, and finally a Moon-centered trail that shows + the trajectory of the spacecraft in the Moon's reference frame.]], + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/scene/solarsystem/missions/apollo/actions.asset b/data/assets/scene/solarsystem/missions/apollo/actions.asset index 68ab8c420e..349b8f262d 100644 --- a/data/assets/scene/solarsystem/missions/apollo/actions.asset +++ b/data/assets/scene/solarsystem/missions/apollo/actions.asset @@ -54,8 +54,8 @@ end) asset.meta = { - Name = "Actions - Apollo missions", - Description = "Actions related to the Apollo missions", + Name = "Apollo - Actions", + Description = "This asset defines actions that apply to all Apollo missions", Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/missions/apollo/apollo_globebrowsing.asset b/data/assets/scene/solarsystem/missions/apollo/apollo_globebrowsing.asset index a32046950d..3df49c9443 100644 --- a/data/assets/scene/solarsystem/missions/apollo/apollo_globebrowsing.asset +++ b/data/assets/scene/solarsystem/missions/apollo/apollo_globebrowsing.asset @@ -39,10 +39,7 @@ local ToggleKaguyaLayer = { Identifier = "os.apollo.moon.ToggleKaguyaLayer", Name = "Toggle Kaguya layer", Command = [[ - openspace.setPropertyValueSingle( - "Scene.Moon.Renderable.Layers.ColorLayers.Kaguya_Utah.Enabled", - not openspace.propertyValue("Scene.Moon.Renderable.Layers.ColorLayers.Kaguya_Utah.Enabled") - ) + openspace.toggleFade("Scene.Moon.Renderable.Layers.ColorLayers.Kaguya_Utah") ]], Documentation = "Toggles Moon Kaguya color layer", GuiPath = "/Missions/Apollo", @@ -80,3 +77,14 @@ asset.onDeinitialize(function() openspace.action.removeAction(DisableApolloSites) openspace.action.removeAction(ToggleKaguyaLayer) end) + + + +asset.meta = { + Name = "Apollo - Globe Actions", + Description = [[This asset defines actions that are used to control the visibility of + features on the Moon's surface as they related to the different landing sites.]], + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/scene/solarsystem/missions/apollo/insignias_map.asset b/data/assets/scene/solarsystem/missions/apollo/insignias_map.asset index ab1828e639..89a8f2b908 100644 --- a/data/assets/scene/solarsystem/missions/apollo/insignias_map.asset +++ b/data/assets/scene/solarsystem/missions/apollo/insignias_map.asset @@ -222,3 +222,14 @@ asset.export(Apollo12) asset.export(Apollo14) asset.export(Apollo15) asset.export(Apollo16) + + + +asset.meta = { + Name = "Apollo - Insignias", + Description = [[This asset shows the location of the different landing sites of the + Apollo missions on the Moon by placing the missions' insignias.]], + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/scene/solarsystem/missions/apollo/mission.asset b/data/assets/scene/solarsystem/missions/apollo/mission.asset index 804cf3e4fa..30849f80d2 100644 --- a/data/assets/scene/solarsystem/missions/apollo/mission.asset +++ b/data/assets/scene/solarsystem/missions/apollo/mission.asset @@ -1,21 +1,21 @@ local Mission = { Identifier = "Apollo", Name = "The Apollo Missions", - Image = "https://solarsystem.nasa.gov/system/downloadable_items/2962_s65-55202.jpg", + Image = "https://data.openspaceproject.com/missions/apollo/2962_s65-55202.jpg", Description = "Apollo was the NASA program that resulted in American astronauts' making a total of 11 spaceflights and walking on the moon. The first four flights tested the equipment used in the Apollo Program. Six of the other seven flights landed on the moon. The first Apollo flight happened in 1968. The first moon landing took place in 1969. The last moon landing was in 1972. A total of 12 astronauts walked on the moon. The astronauts conducted scientific research there. They studied the lunar surface. They collected moon rocks to bring back to Earth.", Actions = { "os.apollo.moon.ToggleKaguyaLayer", "os.apollo.ToggleMoonShading", "os.apollo.ShowInsignias", "os.apollo.HideInsignias" }, Milestones = { { Name = "First image of Earthrise", Date = "1968 DEC 24 12:20:00", - Image = "https://www.nasa.gov/sites/default/files/thumbnails/image/apollo_8_earthrise_1968_as08-14-2383.jpg", + Image = "https://data.openspaceproject.com/missions/apollo/apollo_8_earthrise_1968_as08-14-2383.png", Description = "On Dec. 24, 1968, Apollo 8 astronauts Frank Borman, Jim Lovell, and Bill Anders became the first humans to orbit the Moon, and the first to witness the magnificent sight called 'Earthrise'. As the spacecraft was in the process of rotating, Anders took this iconic picture showing Earth rising over the Moon's horizon." }, { Name = "One giant leap for mankind", Date = "1969 JUL 20 02:56:00", Description = "At 02:56 a.m. UTC Neil Armstrong is ready to plant the first human foot on another world. With more than half a billion people watching on television, he climbs down the ladder and proclaims: 'That's one small step for a man, one giant leap for mankind'. Aldrin joins him shortly, and offers a simple but powerful description of the lunar surface: 'magnificent desolation'. They explore the surface for two and a half hours, collecting samples and taking photographs. They leave behind an American flag, a patch honoring the fallen Apollo 1 crew, and a plaque on one of Eagle's legs. It reads, 'Here men from the planet Earth first set foot upon the moon. July 1969 A.D. We came in peace for all mankind.'", - Image = "https://www.nasa.gov/sites/default/files/images/464487main_AS11-40-5886_full.jpg" + Image = "https://data.openspaceproject.com/missions/apollo/464487main_AS11-40-5886_full.jpg" } }, Phases = { @@ -23,13 +23,13 @@ local Mission = { Name = "Apollo flight 8", TimeRange = { Start = "1968 DEC 21 12:51:00", End = "1968 DEC 27 15:51:42" }, Description = "Apollo 8 was the first crewed spacecraft to successfully orbit the Moon and return to Earth. The Apollo 8 crew were also the first to witness and photograph an Earthrise.", - Image = "https://upload.wikimedia.org/wikipedia/commons/4/47/Ap8-S68-56531.jpg" + Image = "https://data.openspaceproject.com/missions/apollo/Ap8-S68-56531.jpg" }, { Name = "Apollo flight 11", TimeRange = { Start = "1969 JUL 16 13:32:00", End = "1969 JUL 24 16:50:35" }, Description = "Apollo 11 was the first mission to land on the moon. The crew consisted of Neil Armstrong, Commander, Edwin E. 'Buzz' Aldrin Jr., Lunar Module Pilot, and Michael Collins, Command Module Pilot", - Image = "https://www.nasa.gov/sites/default/files/styles/full_width_feature/public/thumbnails/image/s69-31739orig.jpg", + Image = "https://data.openspaceproject.com/missions/apollo/s69-31739orig.jpg", Link = "https://www.nasa.gov/mission_pages/apollo/missions/apollo11.html", Actions = { "os.apollo11.setup.LandingSite", "os.apollo.DisableApolloSites" } }, @@ -37,13 +37,13 @@ local Mission = { Name = "Apollo Flight 15", TimeRange = { Start = "1971 JUL 26 13:34:00", End = "1971 AUG 07 20:45:53" }, Description = "Apollo 15 was the first of the Apollo missions capable of a longer stay time on the moon and greater surface mobility. The crew was the first to use the Lunar Roving Vehicle.", - Image = "https://www.nasa.gov/sites/default/files/styles/full_width/public/thumbnails/image/apollo_15_moon_landing_29_eva3_irwin_w_us_flag_as15-88-11866hr.jpg?itok=oA8gldMa" + Image = "https://data.openspaceproject.com/missions/apollo/apollo_15_moon_landing_29_eva3_irwin_w_us_flag_as15-88-11866hr.jpgitok=oA8gldMa.jpg" }, { Name = "Apollo Flight 17", TimeRange = { Start = "1972 DEC 07 05:33:00", End = "1972 DEC 19 19:54:58" }, Description = "Apollo 17 was the last mission in which humans traveled to the Moon. It was distinguished by extended hardware capability, larger scientific payload capacity and the use of the battery-powered Lunar Roving Vehicle.", - Image = "https://www.nasa.gov/sites/default/files/styles/full_width_feature/public/thumbnails/image/as17-147-22526_orig_1.jpg", + Image = "https://data.openspaceproject.com/missions/apollo/as17-147-22526_orig_1.jpg", Actions = { "os.apollo17.setup.LandingSite", "os.apollo.DisableApolloSites" } } } @@ -57,3 +57,14 @@ end) asset.onDeinitialize(function() openspace.unloadMission(Mission) end) + + + +asset.meta = { + Name = "Apollo - Mission overview", + Description = [[This mission file provides information about the Apollo missions and + their respective timelines.]], + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/scene/solarsystem/missions/artemis/mission.asset b/data/assets/scene/solarsystem/missions/artemis/mission.asset index 44bcce8503..ce8c08f440 100644 --- a/data/assets/scene/solarsystem/missions/artemis/mission.asset +++ b/data/assets/scene/solarsystem/missions/artemis/mission.asset @@ -1,16 +1,14 @@ --- Source: https://solarsystem.nasa.gov/missions/rosetta-philae/in-depth/ - local Mission = { Identifier = "Artemis", Name = "Artemis", TimeRange = { Start = "2022 NOV 16 06:47:00", End = "2022 DEC 11 17:40:30" }, - Image = "https://www.nasa.gov/sites/default/files/thumbnails/image/em1_patch_final.png", + Image = "https://data.openspaceproject.com/missions/artemis/em1_patch_final.png", Description = "With Artemis missions, NASA will land the first woman and first person of color on the Moon, using innovative technologies to explore more of the lunar surface than ever before. We will collaborate with commercial and international partners and establish the first long-term presence on the Moon. Then, we will use what we learn on and around the Moon to take the next giant leap: sending the first astronauts to Mars.", Milestones = { { Name = "Mission launch", Date = "2022 NOV 16 06:47:44", - Image = "https://www.nasa.gov/sites/default/files/thumbnails/image/sls_rocket.jpg", + Image = "https://data.openspaceproject.com/missions/artemis/sls_rocket.png", Description = "Following a successful launch of NASA's Space Launch System (SLS), the most powerful rocket in the world, the agency's Orion spacecraft is on its way to the Moon as part of the Artemis program. Carrying an uncrewed Orion, SLS lifted off for its flight test debut at 1:47 a.m. EST Wednesday from Launch Pad 39B at NASA's Kennedy Space Center in Florida. The launch is the first leg of a mission in which Orion is planned to travel approximately 40,000 miles beyond the Moon and return to Earth over the course of 25.5 days. Known as Artemis I, the mission is a critical part of NASA's Moon to Mars exploration approach, in which the agency explores for the benefit of humanity. It's an important test for the agency before flying astronauts on the Artemis II mission.", Link = "https://www.nasa.gov/press-release/liftoff-nasa-s-artemis-i-mega-rocket-launches-orion-to-moon" }, @@ -18,19 +16,19 @@ local Mission = { Name = "Closest approach to the Moon", Date = "2022 NOV 21 12:57:00", Description = "A portion of the far side of the Moon looms large just beyond the Orion spacecraft in this image taken on the sixth day of the Artemis I mission by a camera on the tip of one of Orion's solar arrays. The spacecraft entered the lunar sphere of influence Sunday, Nov. 20, making the Moon, instead of Earth, the main gravitational force acting on the spacecraft. On Monday, Nov. 21, it came within 80 miles of the lunar surface, the closest approach of the uncrewed Artemis I mission, before moving into a distant retrograde orbit around the Moon. The darkest spot visible near the middle of the image is Mare Orientale.", - Image = "https://blogs.nasa.gov/artemis/wp-content/uploads/sites/303/2022/11/art001e000269-1200x900.jpg", + Image = "https://data.openspaceproject.com/missions/artemis/art001e000269-1200x900.jpg", Link = "https://blogs.nasa.gov/artemis/2022/11/21/artemis-i-flight-day-six-orion-performs-lunar-flyby-closest-outbound-approach/" }, { Name = "Maximum distance from Earth", Date = "2022 NOV 28 00:00:00", Description = "NASA's uncrewed Orion spacecraft reached a maximum distance of nearly 270,000 miles from Earth during the Artemis I flight test before beginning its journey back toward Earth. Orion captured imagery of the Earth and Moon together from its distant lunar orbit, including this image taken from camera on one of the spacecraft's solar array wings.", - Image = "https://www.nasa.gov/sites/default/files/thumbnails/image/orion_day_13_advisory.jpg" + Image = "https://data.openspaceproject.com/missions/artemis/orion_day_13_advisory.jpg" }, { Name = "Orion landing", Description = "NASA's Orion spacecraft for the Artemis I mission splashed down in the Pacific Ocean after a 25.5 day mission to the Moon.", - Image = "https://www.nasa.gov/sites/default/files/thumbnails/image/orion_splashdown_image.jpg", + Image = "https://data.openspaceproject.com/missions/artemis/Orion_splashdown_image.jpg", Date = "2022 DEC 11 17:40:30" } }, diff --git a/data/assets/scene/solarsystem/missions/artemis/trail.asset b/data/assets/scene/solarsystem/missions/artemis/trail.asset index d3a29f95da..ab01e5acc2 100644 --- a/data/assets/scene/solarsystem/missions/artemis/trail.asset +++ b/data/assets/scene/solarsystem/missions/artemis/trail.asset @@ -1,5 +1,5 @@ local earthTransforms = asset.require("scene/solarsystem/planets/earth/transforms") -local moonTransforms = asset.require("scene/solarsystem/planets/earth/moon/moon") +local moon = asset.require("scene/solarsystem/planets/earth/moon/moon") local kernels = asset.require("./kernels") local coreKernels = asset.require("spice/core") @@ -25,13 +25,14 @@ local ArtemisEarthTrail = { GUI = { Name = "Artemis-1 Earth Trail", Path = "/Solar System/Missions/Artemis/Trails", + Focusable = false, Description = "Artemis-1 trail relative to Earth" } } -local ArtemisMoonTrail= { +local ArtemisMoonTrail = { Identifier = "ArtemisMoonTrail", - Parent = moonTransforms.Moon.Identifier, + Parent = moon.Moon.Identifier, Renderable = { Type = "RenderableTrailTrajectory", Translation = { @@ -49,6 +50,7 @@ local ArtemisMoonTrail= { GUI = { Name = "Artemis-1 Moon Trail", Path = "/Solar System/Missions/Artemis/Trails", + Focusable = false, Description = "Artemis-1 trail relative to the Moon" } } diff --git a/data/assets/scene/solarsystem/missions/artemis/transforms.asset b/data/assets/scene/solarsystem/missions/artemis/transforms.asset index 8c32007207..11327e195d 100644 --- a/data/assets/scene/solarsystem/missions/artemis/transforms.asset +++ b/data/assets/scene/solarsystem/missions/artemis/transforms.asset @@ -18,6 +18,7 @@ local ArtemisPosition = { GUI = { Name = "Artemis-1 Position", Path = "/Solar System/Missions/Artemis", + Focusable = false, Hidden = true } } diff --git a/data/assets/scene/solarsystem/missions/bepicolombo/fov/bela.asset b/data/assets/scene/solarsystem/missions/bepicolombo/fov/bela.asset index d60f6f2658..5963055e52 100644 --- a/data/assets/scene/solarsystem/missions/bepicolombo/fov/bela.asset +++ b/data/assets/scene/solarsystem/missions/bepicolombo/fov/bela.asset @@ -22,6 +22,7 @@ local BelaReceiver = { GUI = { Name = "MPO BELA Receiver", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -44,6 +45,7 @@ local BelaTransmitterMain = { GUI = { Name = "MPO BELA Transmitter Main", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -66,6 +68,7 @@ local BelaTransmitterRed = { GUI = { Name = "MPO BELA Transmitter Main", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/bepicolombo/fov/hga.asset b/data/assets/scene/solarsystem/missions/bepicolombo/fov/hga.asset index 730c2841ae..c896e9fc55 100644 --- a/data/assets/scene/solarsystem/missions/bepicolombo/fov/hga.asset +++ b/data/assets/scene/solarsystem/missions/bepicolombo/fov/hga.asset @@ -22,6 +22,7 @@ local HGA = { GUI = { Name = "MPO HGA", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/bepicolombo/fov/mertis.asset b/data/assets/scene/solarsystem/missions/bepicolombo/fov/mertis.asset index 75e04598a6..88143ee020 100644 --- a/data/assets/scene/solarsystem/missions/bepicolombo/fov/mertis.asset +++ b/data/assets/scene/solarsystem/missions/bepicolombo/fov/mertis.asset @@ -22,6 +22,7 @@ local MertisTis = { GUI = { Name = "MPO MERTIS TIS", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -44,6 +45,7 @@ local MertisTisPlanet = { GUI = { Name = "MPO MERTIS TIS Planet", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -66,6 +68,7 @@ local MertisTisSpace = { GUI = { Name = "MPO MERTIS TIS Space", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/bepicolombo/fov/mgns.asset b/data/assets/scene/solarsystem/missions/bepicolombo/fov/mgns.asset index 836712e892..abdcad883d 100644 --- a/data/assets/scene/solarsystem/missions/bepicolombo/fov/mgns.asset +++ b/data/assets/scene/solarsystem/missions/bepicolombo/fov/mgns.asset @@ -22,6 +22,7 @@ local MGNS = { GUI = { Name = "MPO MGNS", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/bepicolombo/fov/mixs.asset b/data/assets/scene/solarsystem/missions/bepicolombo/fov/mixs.asset index 1286f23bfe..a810f1f4ba 100644 --- a/data/assets/scene/solarsystem/missions/bepicolombo/fov/mixs.asset +++ b/data/assets/scene/solarsystem/missions/bepicolombo/fov/mixs.asset @@ -22,6 +22,7 @@ local MIXS_C = { GUI = { Name = "MPO MIXS-C", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -44,6 +45,7 @@ local MIXS_T = { GUI = { Name = "MPO MIXS-T", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/bepicolombo/fov/phebus.asset b/data/assets/scene/solarsystem/missions/bepicolombo/fov/phebus.asset index 18fe04b1c5..b0080f9bde 100644 --- a/data/assets/scene/solarsystem/missions/bepicolombo/fov/phebus.asset +++ b/data/assets/scene/solarsystem/missions/bepicolombo/fov/phebus.asset @@ -22,6 +22,7 @@ local PhebusSlit75 = { GUI = { Name = "MPO Phebus Slit 75", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -44,6 +45,7 @@ local PhebusSlit100 = { GUI = { Name = "MPO Phebus Slit 100", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -66,6 +68,7 @@ local Phebus75 = { GUI = { Name = "MPO Phebus 75", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -88,6 +91,7 @@ local Phebus100 = { GUI = { Name = "MPO Phebus 100", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/bepicolombo/fov/serena.asset b/data/assets/scene/solarsystem/missions/bepicolombo/fov/serena.asset index d2c303524a..525c98578e 100644 --- a/data/assets/scene/solarsystem/missions/bepicolombo/fov/serena.asset +++ b/data/assets/scene/solarsystem/missions/bepicolombo/fov/serena.asset @@ -22,6 +22,7 @@ local SerenaElena = { GUI = { Name = "MPO Serena Elena", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/bepicolombo/fov/serena_anodes.asset b/data/assets/scene/solarsystem/missions/bepicolombo/fov/serena_anodes.asset index a10d997bf1..8e6041cc4b 100644 --- a/data/assets/scene/solarsystem/missions/bepicolombo/fov/serena_anodes.asset +++ b/data/assets/scene/solarsystem/missions/bepicolombo/fov/serena_anodes.asset @@ -22,6 +22,7 @@ local SerenaElenaAN01 = { GUI = { Name = "MPO Serena Elena AN01", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -44,6 +45,7 @@ local SerenaElenaAN02 = { GUI = { Name = "MPO Serena Elena AN02", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -66,6 +68,7 @@ local SerenaElenaAN03 = { GUI = { Name = "MPO Serena Elena AN03", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -88,6 +91,7 @@ local SerenaElenaAN04 = { GUI = { Name = "MPO Serena Elena AN04", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -110,6 +114,7 @@ local SerenaElenaAN05 = { GUI = { Name = "MPO Serena Elena AN05", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -132,6 +137,7 @@ local SerenaElenaAN06 = { GUI = { Name = "MPO Serena Elena AN06", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -154,6 +160,7 @@ local SerenaElenaAN07 = { GUI = { Name = "MPO Serena Elena AN07", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -176,6 +183,7 @@ local SerenaElenaAN08 = { GUI = { Name = "MPO Serena Elena AN08", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -198,6 +206,7 @@ local SerenaElenaAN09 = { GUI = { Name = "MPO Serena Elena AN09", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -220,6 +229,7 @@ local SerenaElenaAN10 = { GUI = { Name = "MPO Serena Elena AN10", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -242,6 +252,7 @@ local SerenaElenaAN11 = { GUI = { Name = "MPO Serena Elena AN11", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -264,6 +275,7 @@ local SerenaElenaAN12 = { GUI = { Name = "MPO Serena Elena AN12", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -286,6 +298,7 @@ local SerenaElenaAN13 = { GUI = { Name = "MPO Serena Elena AN13", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -308,6 +321,7 @@ local SerenaElenaAN14 = { GUI = { Name = "MPO Serena Elena AN14", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -330,6 +344,7 @@ local SerenaElenaAN15 = { GUI = { Name = "MPO Serena Elena AN15", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -352,6 +367,7 @@ local SerenaElenaAN16 = { GUI = { Name = "MPO Serena Elena AN16", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -374,6 +390,7 @@ local SerenaElenaAN17 = { GUI = { Name = "MPO Serena Elena AN17", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -396,6 +413,7 @@ local SerenaElenaAN18 = { GUI = { Name = "MPO Serena Elena AN18", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -418,6 +436,7 @@ local SerenaElenaAN19 = { GUI = { Name = "MPO Serena Elena AN19", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -440,6 +459,7 @@ local SerenaElenaAN20 = { GUI = { Name = "MPO Serena Elena AN20", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -462,6 +482,7 @@ local SerenaElenaAN21 = { GUI = { Name = "MPO Serena Elena AN21", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -484,6 +505,7 @@ local SerenaElenaAN22 = { GUI = { Name = "MPO Serena Elena AN22", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -506,6 +528,7 @@ local SerenaElenaAN23 = { GUI = { Name = "MPO Serena Elena AN23", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -528,6 +551,7 @@ local SerenaElenaAN24 = { GUI = { Name = "MPO Serena Elena AN24", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -550,6 +574,7 @@ local SerenaElenaAN25 = { GUI = { Name = "MPO Serena Elena AN25", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -572,6 +597,7 @@ local SerenaElenaAN26 = { GUI = { Name = "MPO Serena Elena AN26", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -594,6 +620,7 @@ local SerenaElenaAN27 = { GUI = { Name = "MPO Serena Elena AN27", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -616,6 +643,7 @@ local SerenaElenaAN28 = { GUI = { Name = "MPO Serena Elena AN28", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -638,6 +666,7 @@ local SerenaElenaAN29 = { GUI = { Name = "MPO Serena Elena AN29", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -660,6 +689,7 @@ local SerenaElenaAN30 = { GUI = { Name = "MPO Serena Elena AN30", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -682,6 +712,7 @@ local SerenaElenaAN31 = { GUI = { Name = "MPO Serena Elena AN31", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -704,6 +735,7 @@ local SerenaElenaAN32 = { GUI = { Name = "MPO Serena Elena AN32", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/bepicolombo/fov/sibbiosys.asset b/data/assets/scene/solarsystem/missions/bepicolombo/fov/sibbiosys.asset index 1f00714adf..9a6db853a4 100644 --- a/data/assets/scene/solarsystem/missions/bepicolombo/fov/sibbiosys.asset +++ b/data/assets/scene/solarsystem/missions/bepicolombo/fov/sibbiosys.asset @@ -22,6 +22,7 @@ local SimbioSys_HRIC_FPA = { GUI = { Name = "MPO Simbio-Sys HRIC FPA", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -44,6 +45,7 @@ local SimbioSys_HRIC_F550 = { GUI = { Name = "MPO Simbio-Sys HRIC F550", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -66,6 +68,7 @@ local SimbioSys_HRIC_FPAN = { GUI = { Name = "MPO Simbio-Sys HRIC FPAN", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -88,6 +91,7 @@ local SimbioSys_HRIC_F750 = { GUI = { Name = "MPO Simbio-Sys HRIC F750", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -110,6 +114,7 @@ local SimbioSys_HRIC_F880 = { GUI = { Name = "MPO Simbio-Sys HRIC F880", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -132,6 +137,7 @@ local SimbioSys_STC_L = { GUI = { Name = "MPO Simbio-Sys STC L", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -154,6 +160,7 @@ local SimbioSys_STC_H = { GUI = { Name = "MPO Simbio-Sys STC H", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -176,6 +183,7 @@ local SimbioSys_STC_L_F920 = { GUI = { Name = "MPO Simbio-Sys STC L F920", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -198,6 +206,7 @@ local SimbioSys_STC_L_F550 = { GUI = { Name = "MPO Simbio-Sys STC L F550", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -220,6 +229,7 @@ local SimbioSys_STC_L_P700 = { GUI = { Name = "MPO Simbio-Sys STC L P700", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -242,6 +252,7 @@ local SimbioSys_STC_H_P700 = { GUI = { Name = "MPO Simbio-Sys STC H P700", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -264,6 +275,7 @@ local SimbioSys_STC_H_F420 = { GUI = { Name = "MPO Simbio-Sys STC H F420", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -286,6 +298,7 @@ local SimbioSys_STC_H_F750 = { GUI = { Name = "MPO Simbio-Sys STC H F750", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -308,6 +321,7 @@ local SimbioSys_VIHI = { GUI = { Name = "MPO Simbio-Sys VIHI", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/bepicolombo/fov/sixs.asset b/data/assets/scene/solarsystem/missions/bepicolombo/fov/sixs.asset index 78c81c9818..9bb1b17d98 100644 --- a/data/assets/scene/solarsystem/missions/bepicolombo/fov/sixs.asset +++ b/data/assets/scene/solarsystem/missions/bepicolombo/fov/sixs.asset @@ -22,6 +22,7 @@ local SixsX1 = { GUI = { Name = "MPO Sixs X1", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -44,6 +45,7 @@ local SixsX2 = { GUI = { Name = "MPO Sixs X2", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -66,6 +68,7 @@ local SixsX3 = { GUI = { Name = "MPO Sixs X3", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/bepicolombo/fov/startracker.asset b/data/assets/scene/solarsystem/missions/bepicolombo/fov/startracker.asset index f5afe6f213..e274f85e5e 100644 --- a/data/assets/scene/solarsystem/missions/bepicolombo/fov/startracker.asset +++ b/data/assets/scene/solarsystem/missions/bepicolombo/fov/startracker.asset @@ -22,6 +22,7 @@ local StarTracker1 = { GUI = { Name = "MPO Star Tracker 1", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -44,6 +45,7 @@ local StarTracker2 = { GUI = { Name = "MPO Star Tracker 2", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } @@ -66,6 +68,7 @@ local StarTracker3 = { GUI = { Name = "MPO Star Tracker 3", Path = "/Solar System/Missions/BepiColombo/Instruments", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/bepicolombo/mission.asset b/data/assets/scene/solarsystem/missions/bepicolombo/mission.asset index c108ec8b8a..85a952636f 100644 --- a/data/assets/scene/solarsystem/missions/bepicolombo/mission.asset +++ b/data/assets/scene/solarsystem/missions/bepicolombo/mission.asset @@ -1,7 +1,7 @@ local Mission = { Identifier = "BepiColombo", Name = "BepiColombo", - Image = "https://scifleet.esa.int/downloads/bepi_mcs/bepicolombo.png", + Image = "https://data.openspaceproject.com/missions/bepicolombo/bepicolombo.png", Description = [[BepiColombo is Europe's first mission to Mercury. It launched in October 2018 on a journey to the smallest and least explored terrestrial planet in our Solar System. Arriving at Mercury in December 2025, it will endure temperatures in excess of 350°C and gather data during a 1 year nominal mission. The mission comprises two spacecraft: 1. Mercury Planetary Orbiter (MPO), 2. Mercury Magnetospheric Orbiter (MMO). BepiColombo is a joint mission between ESA and the Japan Aerospace Exploration Agency (JAXA), executed under ESA leadership.]], TimeRange = { Start = "2018 OCT 20 01:45:00", diff --git a/data/assets/scene/solarsystem/missions/bepicolombo/trails.asset b/data/assets/scene/solarsystem/missions/bepicolombo/trails.asset index 5dff82569c..06c8fc35ee 100644 --- a/data/assets/scene/solarsystem/missions/bepicolombo/trails.asset +++ b/data/assets/scene/solarsystem/missions/bepicolombo/trails.asset @@ -22,7 +22,8 @@ local BepiColomboTrailSun = { }, GUI = { Name = "BepiColombo Trail (Sun)", - Path = "/Solar System/Missions/BepiColombo" + Path = "/Solar System/Missions/BepiColombo", + Focusable = false } } @@ -43,7 +44,8 @@ local BepiColomboTrailMercury = { }, GUI = { Name = "BepiColombo Trail (Mercury)", - Path = "/Solar System/Missions/BepiColombo" + Path = "/Solar System/Missions/BepiColombo", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/dawn/dawn.asset b/data/assets/scene/solarsystem/missions/dawn/dawn.asset index d2096a1ac5..cf7370afe6 100644 --- a/data/assets/scene/solarsystem/missions/dawn/dawn.asset +++ b/data/assets/scene/solarsystem/missions/dawn/dawn.asset @@ -47,6 +47,7 @@ local DawnPosition = { GUI = { Name = "Dawn Position", Path = "/Solar System/Missions/Dawn", + Focusable = false, Hidden = true } } @@ -94,7 +95,8 @@ local DawnTrail = { }, GUI = { Name = "Dawn Trail", - Path = "/Solar System/Missions/Dawn" + Path = "/Solar System/Missions/Dawn", + Focusable = false } } @@ -116,7 +118,8 @@ local DawnFramingCamera1 = { }, GUI = { Name = "Dawn Framing Camera 1", - Path = "/Solar System/Missions/Dawn" + Path = "/Solar System/Missions/Dawn", + Focusable = false } } @@ -137,7 +140,8 @@ local DawnFramingCamera2 = { }, GUI = { Name = "Dawn Framing Camera 2", - Path = "/Solar System/Missions/Dawn" + Path = "/Solar System/Missions/Dawn", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/dawn/mission.asset b/data/assets/scene/solarsystem/missions/dawn/mission.asset index 5843ccea24..e403767f8a 100644 --- a/data/assets/scene/solarsystem/missions/dawn/mission.asset +++ b/data/assets/scene/solarsystem/missions/dawn/mission.asset @@ -1,33 +1,31 @@ local Mission = { Identifier = "Dawn", Name = "Dawn", - Image = "https://photojournal.jpl.nasa.gov/jpegMod/PIA19375_modest.jpg", + Image = "https://data.openspaceproject.com/missions/dawn/PIA19375_modest.jpg", TimeRange = { Start = "2007 SEP 07 11:34:00", End = "2018 OCT 30 00:00:00" }, Description = "Dawn was the first spacecraft to orbit two extraterrestrial destinations (Vesta and Ceres). When Dawn arrived at Vesta, it became the first spacecraft to orbit an object in the main asteroid belt. When Dawn arrived at Ceres, it was the first spacecraft to visit a dwarf planet.", Milestones = { { Name = "Launch", Date = "2007 SEP 07 11:34:00", - Image = "https://www.nasa.gov/images/content/190740main_dawnlaunch_330.jpg" + Image = "https://data.openspaceproject.com/missions/dawn/190740main_dawnlaunch_330.jpg" }, { Name = "Flyby of Mars", - Date = "2009 FEB 18 00:27:58", - Image = "https://www.nasa.gov/sites/default/files/styles/full_width_feature/public/thumbnails/image/pj41_full.gif" , - Description = "On Dec. 24, 1968, Apollo 8 astronauts Frank Borman, Jim Lovell, and Bill Anders became the first humans to orbit the Moon, and the first to witness the magnificent sight called 'Earthrise'. As the spacecraft was in the process of rotating, Anders took this iconic picture showing Earth rising over the Moon's horizon." + Date = "2009 FEB 18 00:27:58" } }, Phases = { { Name = "Vesta orbit", TimeRange = { Start = "2011 JUL 16 04:47:00", End = "2012 SEP 05 06:26:00" }, - Image = "https://solarsystem.nasa.gov/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDVG9JYTJWNVNTSXBZV1UxWWpJd016a3ROVFUxT1MwME1UZzFMVGxoTWpZdFkyUXpZVEk1T0RKak1UazFCam9HUlZRNkVHUnBjM0J2YzJsMGFXOXVTU0pQYVc1c2FXNWxPeUJtYVd4bGJtRnRaVDBpVUVsQk1UVTJOemhmYUdseVpYTXVhbkJuSWpzZ1ptbHNaVzVoYldVcVBWVlVSaTA0SnlkUVNVRXhOVFkzT0Y5b2FYSmxjeTVxY0djR093WlVPaEZqYjI1MFpXNTBYM1I1Y0dWSklnOXBiV0ZuWlM5cWNHVm5CanNHVkRvUmMyVnlkbWxqWlY5dVlXMWxPZ3BzYjJOaGJBPT0iLCJleHAiOm51bGwsInB1ciI6ImJsb2Jfa2V5In19--046d49cb8eb78db2f7202c135bc43c590c15f213/PIA15678_hires.jpg", + Image = "https://data.openspaceproject.com/missions/dawn/PIA15678_hires.jpg", Description = "Dawn orbited Vesta for more than a year, from July 2011 to September 2012. Its investigation confirmed that Vesta is the parent of the HED (howardites, eucrites, and diogenites) meteorites, which Dawn connected to Vesta's large south polar basin, a priceless cosmic connection between samples in hand and a singular event on a small planet." }, { Name = "Ceres orbit", TimeRange = { Start = "2015 MAR 06 12:29:00", End = "2018 OCT 30 00:00:00" }, - Image = "https://solarsystem.nasa.gov/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDVG9JYTJWNVNTSXBZekk1TTJFMk5tVXRaR1F3TmkwME5XSmpMVGcwWVRNdE5qY3daREJoWkRNek1tWTJCam9HUlZRNkVHUnBjM0J2YzJsMGFXOXVTU0pEYVc1c2FXNWxPeUJtYVd4bGJtRnRaVDBpVUVsQk1qRXdOemt1YW5Cbklqc2dabWxzWlc1aGJXVXFQVlZVUmkwNEp5ZFFTVUV5TVRBM09TNXFjR2NHT3daVU9oRmpiMjUwWlc1MFgzUjVjR1ZKSWc5cGJXRm5aUzlxY0dWbkJqc0dWRG9SYzJWeWRtbGpaVjl1WVcxbE9ncHNiMk5oYkE9PSIsImV4cCI6bnVsbCwicHVyIjoiYmxvYl9rZXkifX0=--84aa86325e1ff663ed2382dd4f30967e4c53e5e8/PIA21079.jpg", + Image = "https://data.openspaceproject.com/missions/dawn/PIA21079.jpg", Description = "After its escape from Vesta and its journey onward, Dawn entered orbit around Ceres in March 2015. Dawn discovered that the inner solar system's only dwarf planet was an ocean world where water and ammonia reacted with silicate rocks. As the ocean froze, salts and other telltale minerals concentrated into deposits that are now exposed in many locations across the surface. Dawn also found organics in several locations on Ceres' surface." } } diff --git a/data/assets/scene/solarsystem/missions/dawn/vesta.asset b/data/assets/scene/solarsystem/missions/dawn/vesta.asset index c8c28c8257..abd80648d7 100644 --- a/data/assets/scene/solarsystem/missions/dawn/vesta.asset +++ b/data/assets/scene/solarsystem/missions/dawn/vesta.asset @@ -127,7 +127,8 @@ local VestaTrail = { }, GUI = { Name = "Vesta Trail", - Path = "/Solar System/Asteroid Belt/Vesta" + Path = "/Solar System/Asteroid Belt/Vesta", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/insight/edl.asset b/data/assets/scene/solarsystem/missions/insight/edl.asset index e37316b37f..f47a53997b 100644 --- a/data/assets/scene/solarsystem/missions/insight/edl.asset +++ b/data/assets/scene/solarsystem/missions/insight/edl.asset @@ -151,6 +151,7 @@ local InsightParent = { GUI = { Name = "InsightParent", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -187,6 +188,7 @@ local Insight_Entry_CapsuleA = { GUI = { Name = "Insight Entry CapsuleA", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -207,6 +209,7 @@ local Insight_Entry_Capsule_Ring = { GUI = { Name = "Insight Entry Capsule Ring", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -227,6 +230,7 @@ local Insight_Entry_Capsule_Plugs = { GUI = { Name = "Insight Entry Capsule Plugs", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -247,6 +251,7 @@ local Insight_Entry_Heatshield = { GUI = { Name = "Insight Entry Heatshield", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -268,6 +273,7 @@ local Insight_Parachute_0 = { GUI = { Name = "Insight Parachute0", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -289,6 +295,7 @@ local Insight_Parachute_Cords_0 = { GUI = { Name = "Insight ParachuteC0", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -310,6 +317,7 @@ local Insight_Parachute_20 = { GUI = { Name = "Insight Parachute20", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -331,6 +339,7 @@ local Insight_Parachute_Cords_20 = { GUI = { Name = "Insight ParachuteC20", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -352,6 +361,7 @@ local Insight_Parachute_40 = { GUI = { Name = "Insight Parachute40", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -373,6 +383,7 @@ local Insight_Parachute_Cords_40 = { GUI = { Name = "Insight ParachuteC40", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -389,6 +400,7 @@ local Insight_Lander_A001 = { GUI = { Name = "Insight Lander A001", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -405,6 +417,7 @@ local Insight_Lander_A002 = { GUI = { Name = "Insight Lander A002", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -421,6 +434,7 @@ local Insight_Lander_A003 = { GUI = { Name = "Insight Lander A003", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -437,6 +451,7 @@ local Insight_Lander_A004 = { GUI = { Name = "Insight Lander A004", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -453,6 +468,7 @@ local Insight_Lander_A005 = { GUI = { Name = "Insight Lander A005", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -469,6 +485,7 @@ local Insight_Lander_A006 = { GUI = { Name = "Insight Lander A006", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -485,6 +502,7 @@ local Insight_Lander_A007 = { GUI = { Name = "Insight Lander A007", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -501,6 +519,7 @@ local Insight_Lander_A008 = { GUI = { Name = "Insight Lander A008", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -517,6 +536,7 @@ local Insight_Lander_foil1 = { GUI = { Name = "Insight Lander foil", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -533,6 +553,7 @@ local Insight_Lander_Tex01 = { GUI = { Name = "Insight Lander Tex01", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -549,6 +570,7 @@ local Insight_Lander_Tex02 = { GUI = { Name = "Insight Lander Tex02", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -570,6 +592,7 @@ local Insight_Legs_Stowed_tex = { GUI = { Name = "Insight legs_stow_tex", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -591,6 +614,7 @@ local Insight_Legs_Stowed_AO06 = { GUI = { Name = "Insight legs_stow_AO", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -611,6 +635,7 @@ local Insight_Legs_Deployed_tex = { GUI = { Name = "Insight legs_deploy_tex", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -631,6 +656,7 @@ local Insight_Legs_Deployed_AO06 = { GUI = { Name = "Insight legs_deploy_AO", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -647,6 +673,7 @@ local Insight_Panels_Stowed_tex = { GUI = { Name = "Insight panels_stow_tex", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -663,6 +690,7 @@ local Insight_Panels_Stowed_tex2 = { GUI = { Name = "Insight panels_stow_tex2", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -679,6 +707,7 @@ local Insight_Panels_Stowed_AO01 = { GUI = { Name = "Insight panels_stow_AO", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -699,6 +728,7 @@ local Insight_Panels_Deployed_tex = { GUI = { Name = "Insight panels_deploy_tex", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -718,7 +748,9 @@ local Insight_Panels_Deployed_tex2 = { }, GUI = { Name = "Insight panels_deploy_tex2", - Path = "/Solar System/Missions/Insight" + Path = "/Solar System/Missions/Insight", + Focusable = false, + Hidden = true } } @@ -738,6 +770,7 @@ local Insight_Panels_Deployed_AO06 = { GUI = { Name = "Insight panels_deploy_AO", Path = "/Solar System/Missions/Insight", + Focusable = false, Hidden = true } } @@ -766,7 +799,8 @@ local Insight_Trail = { }, GUI = { Name = "Insight Trail", - Path = "/Solar System/Missions/Insight" + Path = "/Solar System/Missions/Insight", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/interstellar_horizons.asset b/data/assets/scene/solarsystem/missions/interstellar_horizons.asset new file mode 100644 index 0000000000..30a3e87b02 --- /dev/null +++ b/data/assets/scene/solarsystem/missions/interstellar_horizons.asset @@ -0,0 +1,3 @@ +asset.require("./newhorizons/horizons") +asset.require("./pioneer/horizons") +asset.require("./voyager/horizons") diff --git a/data/assets/scene/solarsystem/missions/juice/dashboard.asset b/data/assets/scene/solarsystem/missions/juice/dashboard.asset index fdd20f5580..0f9693a22a 100644 --- a/data/assets/scene/solarsystem/missions/juice/dashboard.asset +++ b/data/assets/scene/solarsystem/missions/juice/dashboard.asset @@ -9,9 +9,9 @@ local DistanceJuiceJupiter = { Identifier = "JuiceJupiterDistance", Enabled = asset.enabled, SourceType = "Node", - SourceNodeName = juice.Juice.Identifier, + SourceNodeIdentifier = juice.Juice.Identifier, DestinationType = "Node", - DestinationNodeName = jupiter.Jupiter.Identifier, + DestinationNodeIdentifier = jupiter.Jupiter.Identifier, GuiName = "Juice - Jupiter Distance" } @@ -20,9 +20,9 @@ local DistanceJuiceGanymede = { Identifier = "JuiceGanymedeDistance", Enabled = asset.enabled, SourceType = "Node", - SourceNodeName = juice.Juice.Identifier, + SourceNodeIdentifier = juice.Juice.Identifier, DestinationType = "Node", - DestinationNodeName = ganymede.Ganymede.Identifier, + DestinationNodeIdentifier = ganymede.Ganymede.Identifier, GuiName = "Juice - Ganymede Distance" } diff --git a/data/assets/scene/solarsystem/missions/juice/fieldlines.asset b/data/assets/scene/solarsystem/missions/juice/fieldlines.asset index e578bd3471..080868dc08 100644 --- a/data/assets/scene/solarsystem/missions/juice/fieldlines.asset +++ b/data/assets/scene/solarsystem/missions/juice/fieldlines.asset @@ -18,11 +18,13 @@ local GanymedeMagnetosphere = { SourceFolder = data, LineWidth = 3.0, InputFileType = "Json", + ShowAtAllTimes = true, ColorMethod = "By Quantity", ColorQuantity = 0, - ColorTableRanges = { { 62.556353386366766, 1665.5534182835445 } }, + ColorTableRanges = { { 62.556353386366766, 1665.5534182835445} }, + ColorMinMaxRange = { 0, 10000 }, ColorTablePaths = { asset.resource("CMR-illuminance2.txt") }, - Color = { 0.03, 0.0, 0.0, 1.0 }, + Color = { 1.0, 0.725, 0.75, 0.8 }, ParticleSpacing = 42.0, ParticleSize = 30.0, FlowColor = { 1.0, 1.0, 1.0, 0.1 }, diff --git a/data/assets/scene/solarsystem/missions/juice/fov/gala.asset b/data/assets/scene/solarsystem/missions/juice/fov/gala.asset index 999e8e73c8..3c2d8707a0 100644 --- a/data/assets/scene/solarsystem/missions/juice/fov/gala.asset +++ b/data/assets/scene/solarsystem/missions/juice/fov/gala.asset @@ -27,6 +27,7 @@ local Gala = { GUI = { Name = "Gala FOV", Path = "/Solar System/Missions/Juice/Instruments", + Focusable = false, Description = "The field-of-view for the Ganymede Laster Altimeter (GALA) instrument" } } diff --git a/data/assets/scene/solarsystem/missions/juice/fov/janus.asset b/data/assets/scene/solarsystem/missions/juice/fov/janus.asset index 65d440a769..b1b689afae 100644 --- a/data/assets/scene/solarsystem/missions/juice/fov/janus.asset +++ b/data/assets/scene/solarsystem/missions/juice/fov/janus.asset @@ -33,6 +33,7 @@ local Janus = { GUI = { Name = "Janus FOV", Path = "/Solar System/Missions/Juice/Instruments", + Focusable = false, Description = "The field-of-view for the JANUS instrument onboard Juice" } } diff --git a/data/assets/scene/solarsystem/missions/juice/fov/jmc.asset b/data/assets/scene/solarsystem/missions/juice/fov/jmc.asset index 57e183f1e7..4e1f2a3ce5 100644 --- a/data/assets/scene/solarsystem/missions/juice/fov/jmc.asset +++ b/data/assets/scene/solarsystem/missions/juice/fov/jmc.asset @@ -27,6 +27,7 @@ local JMC1 = { GUI = { Name = "JUICE_JMC-1 FOV", Path = "/Solar System/Missions/Juice/Instruments", + Focusable = false, Description = "The field-of-views for the Juice Monitoring cameras" } } @@ -55,6 +56,7 @@ local JMC2 = { GUI = { Name = "JUICE_JMC-2 FOV", Path = "/Solar System/Missions/Juice/Instruments", + Focusable = false, Description = "The field-of-views for the Juice Monitoring cameras" } } diff --git a/data/assets/scene/solarsystem/missions/juice/fov/majis.asset b/data/assets/scene/solarsystem/missions/juice/fov/majis.asset index 2802dbce6a..85aceaa935 100644 --- a/data/assets/scene/solarsystem/missions/juice/fov/majis.asset +++ b/data/assets/scene/solarsystem/missions/juice/fov/majis.asset @@ -27,6 +27,7 @@ local MajisVisnir = { GUI = { Name = "Majis Visnir FOV", Path = "/Solar System/Missions/Juice/Instruments", + Focusable = false, Description = [[ The field-of-view for the Moon and Jupiter Imaging Spectrometer measuring in the visible and near-infrared spectra (0.4-1.9 um and 1.5-5.7 um). @@ -57,7 +58,8 @@ local MajisVisnirB2 = { }, GUI = { Name = "Majis Visnir B2 FOV", - Path = "/Solar System/Missions/Juice/Instruments" + Path = "/Solar System/Missions/Juice/Instruments", + Focusable = false } } @@ -84,7 +86,8 @@ local MajisVisnirB4 = { }, GUI = { Name = "Majis Visnir B4 FOV", - Path = "/Solar System/Missions/Juice/Instruments" + Path = "/Solar System/Missions/Juice/Instruments", + Focusable = false } } @@ -111,7 +114,8 @@ local MajisIr = { }, GUI = { Name = "Majis IR FOV", - Path = "/Solar System/Missions/Juice/Instruments" + Path = "/Solar System/Missions/Juice/Instruments", + Focusable = false } } @@ -138,7 +142,8 @@ local MajisIrB2 = { }, GUI = { Name = "Majis IR B2 FOV", - Path = "/Solar System/Missions/Juice/Instruments" + Path = "/Solar System/Missions/Juice/Instruments", + Focusable = false } } @@ -165,7 +170,8 @@ local MajisIrB4 = { }, GUI = { Name = "Majis IR B4 FOV", - Path = "/Solar System/Missions/Juice/Instruments" + Path = "/Solar System/Missions/Juice/Instruments", + Focusable = false } } @@ -193,6 +199,7 @@ local Majis = { GUI = { Name = "Majis FOV", Path = "/Solar System/Missions/Juice/Instruments", + Focusable = false, Description = [[ The field-of-view for the Moon and Jupiter Imaging Spectrometer measuring in the visible and near-infrared spectra (0.4-1.9 um and 1.5-5.7 um). diff --git a/data/assets/scene/solarsystem/missions/juice/fov/navcam.asset b/data/assets/scene/solarsystem/missions/juice/fov/navcam.asset index 1adead87e0..7704a6f513 100644 --- a/data/assets/scene/solarsystem/missions/juice/fov/navcam.asset +++ b/data/assets/scene/solarsystem/missions/juice/fov/navcam.asset @@ -27,6 +27,7 @@ local NavCam = { GUI = { Name = "NavCam FOV", Path = "/Solar System/Missions/Juice/Instruments", + Focusable = false, Description = "The camera onboard Juice used to navigate by the stars" } } diff --git a/data/assets/scene/solarsystem/missions/juice/fov/rime.asset b/data/assets/scene/solarsystem/missions/juice/fov/rime.asset index 8f9aeccf5e..9a299c717c 100644 --- a/data/assets/scene/solarsystem/missions/juice/fov/rime.asset +++ b/data/assets/scene/solarsystem/missions/juice/fov/rime.asset @@ -28,6 +28,7 @@ local RimeBase = { GUI = { Name = "Rime Base FOV", Path = "/Solar System/Missions/Juice/Instruments", + Focusable = false, Description = "The location of the base for the RIME instrument onboard Juice" } } @@ -57,6 +58,7 @@ local Rime = { GUI = { Name = "Rime FOV", Path = "/Solar System/Missions/Juice/Instruments", + Focusable = false, Description = "The location of the RIME instrument onboard Juice" } } diff --git a/data/assets/scene/solarsystem/missions/juice/fov/startracker.asset b/data/assets/scene/solarsystem/missions/juice/fov/startracker.asset index 42a7fefc8e..96bd5ebbd7 100644 --- a/data/assets/scene/solarsystem/missions/juice/fov/startracker.asset +++ b/data/assets/scene/solarsystem/missions/juice/fov/startracker.asset @@ -27,6 +27,7 @@ local StarOh1 = { GUI = { Name = "Star Tracker OH1 FOV", Path = "/Solar System/Missions/Juice/Instruments", + Focusable = false, Description = "The first head of the Hydra star tracking system" } } @@ -55,6 +56,7 @@ local StarOh2 = { GUI = { Name = "Star Tracker OH2 FOV", Path = "/Solar System/Missions/Juice/Instruments", + Focusable = false, Description = "The second head of the Hydra star tracking system" } } @@ -83,6 +85,7 @@ local StarOh3 = { GUI = { Name = "Star Tracker OH3 FOV", Path = "/Solar System/Missions/Juice/Instruments", + Focusable = false, Description = "The third head of the Hydra star tracking system" } } diff --git a/data/assets/scene/solarsystem/missions/juice/fov/swi.asset b/data/assets/scene/solarsystem/missions/juice/fov/swi.asset index 8e06bff28e..35b3f98291 100644 --- a/data/assets/scene/solarsystem/missions/juice/fov/swi.asset +++ b/data/assets/scene/solarsystem/missions/juice/fov/swi.asset @@ -27,7 +27,8 @@ local SwiCh2 = { }, GUI = { Name = "SWI CH2 FOV", - Path = "/Solar System/Missions/Juice/Instruments" + Path = "/Solar System/Missions/Juice/Instruments", + Focusable = false } } @@ -62,6 +63,7 @@ local SwiFull = { GUI = { Name = "SWI Full FOV", Path = "/Solar System/Missions/Juice/Instruments", + Focusable = false, Description = "The field-of-view for the full SWI instrument onboard Juice" } } @@ -98,7 +100,8 @@ local SwiFullGCO500 = { }, GUI = { Name = "SWI Full GCO500 FOV", - Path = "/Solar System/Missions/Juice/Instruments" + Path = "/Solar System/Missions/Juice/Instruments", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/juice/fov/uvs.asset b/data/assets/scene/solarsystem/missions/juice/fov/uvs.asset index e264b5b0fd..6359822729 100644 --- a/data/assets/scene/solarsystem/missions/juice/fov/uvs.asset +++ b/data/assets/scene/solarsystem/missions/juice/fov/uvs.asset @@ -27,6 +27,7 @@ local UVS = { GUI = { Name = "UVS FOV", Path = "/Solar System/Missions/Juice/Instruments", + Focusable = false, Description = "The field-of-view for the UVS instrument onboard Juice" } } diff --git a/data/assets/scene/solarsystem/missions/juice/mission.asset b/data/assets/scene/solarsystem/missions/juice/mission.asset index 3554bc5c5f..fdd2786bed 100644 --- a/data/assets/scene/solarsystem/missions/juice/mission.asset +++ b/data/assets/scene/solarsystem/missions/juice/mission.asset @@ -1,7 +1,7 @@ local Mission = { Identifier = "Juice", Name = "Juice", - Image = "https://www.esa.int/var/esa/storage/images/science_exploration/space_science/juice/23388092-2-eng-GB/Juice_pillars.jpg", + Image = "https://data.openspaceproject.com/missions/juice/Juice_pillars.jpg", Description = "ESA's Jupiter Icy Moons Explorer, Juice, will make detailed observations of the giant gas planet and its three large ocean-bearing moons - Ganymede, Callisto and Europa - with a suite of remote sensing, geophysical, and in situ instruments. The mission will characterize these moons as both planetary objects and possible habitats, explore Jupiter's complex environment in depth, and study the wider Jupiter system as an archetype for gas giants across the Universe.", Milestones = { { diff --git a/data/assets/scene/solarsystem/missions/juice/plane.asset b/data/assets/scene/solarsystem/missions/juice/plane.asset index 39acf75d8b..e2becf8d05 100644 --- a/data/assets/scene/solarsystem/missions/juice/plane.asset +++ b/data/assets/scene/solarsystem/missions/juice/plane.asset @@ -28,6 +28,7 @@ local xy_n = { GUI = { Name = "Ganymede XY Plane N", Path = "/Solar System/Missions/Juice/Plane", + Focusable = false, Description = "A cut plane in Ganymede's XY plane showing the number of particles" } } @@ -44,6 +45,7 @@ local xy_t = { GUI = { Name = "Ganymede XY Plane T", Path = "/Solar System/Missions/Juice/Plane", + Focusable = false, Description = "A cut plane in Ganymede's XY plane showing the temperature" } } @@ -60,6 +62,7 @@ local xy_u = { GUI = { Name = "Ganymede XY Plane U", Path = "/Solar System/Missions/Juice/Plane", + Focusable = false, Description = [[A cut plane in Ganymede's XY plane showing the strength of the magnetic field]] } @@ -77,6 +80,7 @@ local xy_utot = { GUI = { Name = "Ganymede XY Plane U_tot", Path = "/Solar System/Missions/Juice/Plane", + Focusable = false, Description = [[A cut plane in Ganymede's XY plane showing the X, Y, and Z components of the magnetic field mapped to the RGB components]] } @@ -94,6 +98,7 @@ local xy_ux = { GUI = { Name = "Ganymede XY Plane Ux", Path = "/Solar System/Missions/Juice/Plane", + Focusable = false, Description = [[A cut plane in Ganymede's XY plane showing the X component of Ganymede's magnetic field]] } @@ -111,6 +116,7 @@ local xy_uy = { GUI = { Name = "Ganymede XY Plane Uy", Path = "/Solar System/Missions/Juice/Plane", + Focusable = false, Description = [[A cut plane in Ganymede's XY plane showing the Y component of Ganymede's magnetic field]] } @@ -128,6 +134,7 @@ local xy_uz = { GUI = { Name = "Ganymede XY Plane Uz", Path = "/Solar System/Missions/Juice/Plane", + Focusable = false, Description = [[A cut plane in Ganymede's XY plane showing the Z component of Ganymede's magnetic field]] } @@ -151,6 +158,7 @@ local xz_n = { GUI = { Name = "Ganymede XZ Plane N", Path = "/Solar System/Missions/Juice/Plane", + Focusable = false, Description = "A cut plane in Ganymede's XZ plane showing the number of particles" } } @@ -173,6 +181,7 @@ local xz_t = { GUI = { Name = "Ganymede XZ Plane T", Path = "/Solar System/Missions/Juice/Plane", + Focusable = false, Description = "A cut plane in Ganymede's XZ plane showing the temperature" } } @@ -195,6 +204,7 @@ local xz_u = { GUI = { Name = "Ganymede XZ Plane U", Path = "/Solar System/Missions/Juice/Plane", + Focusable = false, Description = [[A cut plane in Ganymede's XZ plane showing the strength of the magnetic field]] } @@ -218,6 +228,7 @@ local xz_utot = { GUI = { Name = "Ganymede XZ Plane U_tot", Path = "/Solar System/Missions/Juice/Plane", + Focusable = false, Description = [[A cut plane in Ganymede's XZ plane showing the X, Y, and Z components of the magnetic field mapped to the RGB components]] } @@ -241,6 +252,7 @@ local xz_ux = { GUI = { Name = "Ganymede XZ Plane Ux", Path = "/Solar System/Missions/Juice/Plane", + Focusable = false, Description = [[A cut plane in Ganymede's XZ plane showing the X component of Ganymede's magnetic field]] } @@ -264,6 +276,7 @@ local xz_uy = { GUI = { Name = "Ganymede XZ Plane Uy", Path = "/Solar System/Missions/Juice/Plane", + Focusable = false, Description = [[A cut plane in Ganymede's XZ plane showing the Y component of Ganymede's magnetic field]] } @@ -287,6 +300,7 @@ local xz_uz = { GUI = { Name = "Ganymede XZ Plane Uz", Path = "/Solar System/Missions/Juice/Plane", + Focusable = false, Description = [[A cut plane in Ganymede's XZ plane showing the Z component of Ganymede's magnetic field]] } diff --git a/data/assets/scene/solarsystem/missions/juice/trails/earth.asset b/data/assets/scene/solarsystem/missions/juice/trails/earth.asset index 278ed32b85..cf590c47eb 100644 --- a/data/assets/scene/solarsystem/missions/juice/trails/earth.asset +++ b/data/assets/scene/solarsystem/missions/juice/trails/earth.asset @@ -22,6 +22,7 @@ local JuiceTrailEarth = { GUI = { Name = "Juice Trail (Earth)", Path = "/Solar System/Missions/Juice", + Focusable = false, Description = "Juice's trajectory relative to the Earth barycenter" } } diff --git a/data/assets/scene/solarsystem/missions/juice/trails/ganymede.asset b/data/assets/scene/solarsystem/missions/juice/trails/ganymede.asset index 6d466cda2d..61b73a9803 100644 --- a/data/assets/scene/solarsystem/missions/juice/trails/ganymede.asset +++ b/data/assets/scene/solarsystem/missions/juice/trails/ganymede.asset @@ -22,6 +22,7 @@ local JuiceTrailGanymede = { GUI = { Name = "Juice Trail (Ganymede)", Path = "/Solar System/Missions/Juice", + Focusable = false, Description = "Juice's trajectory relative to Ganymede" } } diff --git a/data/assets/scene/solarsystem/missions/juice/trails/jupiter.asset b/data/assets/scene/solarsystem/missions/juice/trails/jupiter.asset index e1e77f21ea..e8641141c5 100644 --- a/data/assets/scene/solarsystem/missions/juice/trails/jupiter.asset +++ b/data/assets/scene/solarsystem/missions/juice/trails/jupiter.asset @@ -22,6 +22,7 @@ local JuiceTrailJupiter = { GUI = { Name = "Juice Trail (Jupiter)", Path = "/Solar System/Missions/Juice", + Focusable = false, Description = "Juice's trajectory relative to Jupiter" } } diff --git a/data/assets/scene/solarsystem/missions/juice/trails/ssb.asset b/data/assets/scene/solarsystem/missions/juice/trails/ssb.asset index aad27fb39a..287fed03f2 100644 --- a/data/assets/scene/solarsystem/missions/juice/trails/ssb.asset +++ b/data/assets/scene/solarsystem/missions/juice/trails/ssb.asset @@ -22,6 +22,7 @@ local JuiceTrail = { GUI = { Name = "Juice Trail", Path = "/Solar System/Missions/Juice", + Focusable = false, Description = "Juice's trajectory relative to the solar system's barycenter" } } diff --git a/data/assets/scene/solarsystem/missions/juice/transforms.asset b/data/assets/scene/solarsystem/missions/juice/transforms.asset index d5967031cd..5caa44cf4d 100644 --- a/data/assets/scene/solarsystem/missions/juice/transforms.asset +++ b/data/assets/scene/solarsystem/missions/juice/transforms.asset @@ -43,8 +43,9 @@ local GanymedePosition = { } }, GUI = { - Path = "/Solar System/Planets/Jupiter/Moons", - Description = "Ganymede's position relative to Jupiter as an inertial reference frame" + Path = "/Solar System/Planets/Jupiter/Major Moons/Ganymede", + Description = "Ganymede's position relative to Jupiter as an inertial reference frame", + Hidden = true } } diff --git a/data/assets/scene/solarsystem/missions/juno/juno.asset b/data/assets/scene/solarsystem/missions/juno/juno.asset index 89eef4a490..9434c827ad 100644 --- a/data/assets/scene/solarsystem/missions/juno/juno.asset +++ b/data/assets/scene/solarsystem/missions/juno/juno.asset @@ -76,7 +76,8 @@ local JunoTrail = { }, GUI = { Name = "Juno Trail", - Path = "/Solar System/Missions/Juno" + Path = "/Solar System/Missions/Juno", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/juno/mission.asset b/data/assets/scene/solarsystem/missions/juno/mission.asset index b823e46e3f..94e3a8a31e 100644 --- a/data/assets/scene/solarsystem/missions/juno/mission.asset +++ b/data/assets/scene/solarsystem/missions/juno/mission.asset @@ -1,14 +1,12 @@ local Mission = { Identifier = "Juno", Name = "Juno", - Image = "https://upload.wikimedia.org/wikipedia/commons/3/32/Juno_mission_insignia.svg", + Image = "https://data.openspaceproject.com/missions/juno/Juno_mission_insignia.svg", Description = "On August 5, 2011, NASA's Juno spacecraft embarked on a 5-year journey to our solar system's largest planet - the gas giant Jupiter. Its mission: to probe beneath the planet's dense clouds and answer questions about the origin and evolution of Jupiter, our solar system, and giant planets in general across the cosmos. Juno arrived at Jupiter on July 4, 2016, after a 5-year, 1.7-billion-mile journey, and settled into a 53-day polar orbit stretching from just above Jupiter's cloud tops to the outer reaches of the Jovian magnetosphere.", Milestones = { { Name = "Arrival at Jupiter", - Date = "2016 JUL 04 00:00:00", - Image = "https://www.nasa.gov/sites/default/files/styles/full_width_feature/public/thumbnails/image/pj41_full.gif" , - Description = "On Dec. 24, 1968, Apollo 8 astronauts Frank Borman, Jim Lovell, and Bill Anders became the first humans to orbit the Moon, and the first to witness the magnificent sight called 'Earthrise'. As the spacecraft was in the process of rotating, Anders took this iconic picture showing Earth rising over the Moon's horizon." + Date = "2016 JUL 04 00:00:00" } }, Phases = { @@ -16,7 +14,7 @@ local Mission = { Name = "Journey to Jupiter", TimeRange = { Start = "2011 AUG 05 16:25:00", End = "2016 JUL 04 00:00:00" }, Description = "Juno arrived at Jupiter on July 4, 2016, after a five-year, 1,740-million-mile journey, and settled into a 53-day polar orbit stretching from just above Jupiter's cloud tops to the outer reaches of the Jovian magnetosphere.", - Image = "https://d2pn8kiwq2w21t.cloudfront.net/original_images/jpegPIA22946.jpg", + Image = "https://data.openspaceproject.com/missions/juno/PIA22946_modest.jpg", Phases = { { Name = "Deep space maneuevers", @@ -28,12 +26,12 @@ local Mission = { Name = "Mission", TimeRange = { Start = "2016 JUL 04 00:00:00", End = "2021 AUG 01 00:00:00" }, Description = "Juno's discoveries have revolutionized our understanding of Jupiter and solar system formation. During the prime mission's 35 orbits of Jupiter, Juno collected more than three terabits (375 gigabytes) of science data and provided dazzling views of Jupiter and its satellites, all processed by citizen scientists with NASA's first-ever camera dedicated to public outreach. Juno's many discoveries have changed our view of Jupiter's atmosphere and interior, revealing an atmospheric weather layer that extends far beyond its clouds and a deep interior with a diluted, or 'fuzzy,' heavy element core. Near the end of the prime mission, as the spacecraft's orbit evolved, flybys of the moon Ganymede initiated Juno's transition into a full Jovian system explorer.", - Image = "https://www.nasa.gov/sites/default/files/styles/full_width_feature/public/thumbnails/image/pia22692_hires.jpg" + Image = "https://data.openspaceproject.com/missions/juno/PIA22692.jpg" }, { Name = "Extended Mission", TimeRange = { Start = "2021 AUG 01 00:00:00", End = "2025 Sep 01 00:00:00" }, - Image = "https://www.nasa.gov/sites/default/files/styles/full_width_feature/public/thumbnails/image/pia25015.jpg" + Image = "https://data.openspaceproject.com/missions/juno/PIA25015.jpg" } } } diff --git a/data/assets/scene/solarsystem/missions/messenger/dashboard.asset b/data/assets/scene/solarsystem/missions/messenger/dashboard.asset index a43bebb168..f8cb849e1e 100644 --- a/data/assets/scene/solarsystem/missions/messenger/dashboard.asset +++ b/data/assets/scene/solarsystem/missions/messenger/dashboard.asset @@ -8,9 +8,9 @@ local Distance = { Identifier = "MessengerDistance", GuiName = "Messenger - Mercury Distance", SourceType = "Node", - SourceNodeName = messenger.Messenger.Identifier, + SourceNodeIdentifier = messenger.Messenger.Identifier, DestinationType = "Node", - DestinationNodeName = mercury.Mercury.Identifier + DestinationNodeIdentifier = mercury.Mercury.Identifier } diff --git a/data/assets/scene/solarsystem/missions/messenger/messenger.asset b/data/assets/scene/solarsystem/missions/messenger/messenger.asset index 04805ebcab..fb0dcd0b6c 100644 --- a/data/assets/scene/solarsystem/missions/messenger/messenger.asset +++ b/data/assets/scene/solarsystem/missions/messenger/messenger.asset @@ -59,7 +59,9 @@ local MessengerProbeBlack = { }, GUI = { Name = "MessengerProbe Black", - Path = "/Solar System/Missions/Messenger" + Path = "/Solar System/Missions/Messenger", + Focusable = false, + Hidden = true } } @@ -76,7 +78,9 @@ local MessengerProbeFoil = { }, GUI = { Name = "MessengerProbe foil", - Path = "/Solar System/Missions/Messenger" + Path = "/Solar System/Missions/Messenger", + Focusable = false, + Hidden = true } } @@ -93,7 +97,9 @@ local MessengerProbeHeatShield = { }, GUI = { Name = "MessengerProbe Heat Shield", - Path = "/Solar System/Missions/Messenger" + Path = "/Solar System/Missions/Messenger", + Focusable = false, + Hidden = true } } @@ -110,7 +116,9 @@ local MessengerProbeMetal = { }, GUI = { Name = "MessengerProbe Metal", - Path = "/Solar System/Missions/Messenger" + Path = "/Solar System/Missions/Messenger", + Focusable = false, + Hidden = true } } @@ -127,7 +135,9 @@ local MessengerProbePanels = { }, GUI = { Name = "MessengerProbe Panels", - Path = "/Solar System/Missions/Messenger" + Path = "/Solar System/Missions/Messenger", + Focusable = false, + Hidden = true } } @@ -149,7 +159,8 @@ local MessengerTrail = { }, GUI = { Name = "Messenger Trail", - Path = "/Solar System/Missions/Messenger" + Path = "/Solar System/Missions/Messenger", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/newhorizons/actions.asset b/data/assets/scene/solarsystem/missions/newhorizons/actions.asset index 0d632d4a92..139f41d1bc 100644 --- a/data/assets/scene/solarsystem/missions/newhorizons/actions.asset +++ b/data/assets/scene/solarsystem/missions/newhorizons/actions.asset @@ -147,12 +147,7 @@ local DecreaseHeightmapCharon = { local TogglePlutoTrail = { Identifier = "os.newhorizons.TogglePlutoTrail", Name = "Toggle Pluto trail", - Command = [[ - openspace.setPropertyValueSingle( - "Scene.PlutoBarycentricTrail.Renderable.Enabled", - not openspace.propertyValue("Scene.PlutoBarycentricTrail.Renderable.Enabled") - ) - ]], + Command = [[openspace.toggleFade("Scene.PlutoBarycentricTrail.Renderable")]], Documentation = "Toggles the visibility of the trail behind Pluto", GuiPath = "/Missions/New Horizons", IsLocal = false @@ -162,30 +157,12 @@ local TogglePlutoLabels = { Identifier = "os.newhorizons.TogglePlutoLabels", Name = "Toggle Pluto labels", Command = [[ - openspace.setPropertyValueSingle( - "Scene.PlutoText.Renderable.Enabled", - not openspace.propertyValue("Scene.PlutoText.Renderable.Enabled") - ) - openspace.setPropertyValueSingle( - "Scene.CharonText.Renderable.Enabled", - not openspace.propertyValue("Scene.CharonText.Renderable.Enabled") - ) - openspace.setPropertyValueSingle( - "Scene.HydraText.Renderable.Enabled", - not openspace.propertyValue("Scene.HydraText.Renderable.Enabled") - ) - openspace.setPropertyValueSingle( - "Scene.NixText.Renderable.Enabled", - not openspace.propertyValue("Scene.NixText.Renderable.Enabled") - ) - openspace.setPropertyValueSingle( - "Scene.KerberosText.Renderable.Enabled", - not openspace.propertyValue("Scene.KerberosText.Renderable.Enabled") - ) - openspace.setPropertyValueSingle( - "Scene.StyxText.Renderable.Enabled", - not openspace.propertyValue("Scene.StyxText.Renderable.Enabled") - ) + openspace.toggleFade("Scene.PlutoText.Renderable") + openspace.toggleFade("Scene.CharonText.Renderable") + openspace.toggleFade("Scene.HydraText.Renderable") + openspace.toggleFade("Scene.NixText.Renderable") + openspace.toggleFade("Scene.KerberosText.Renderable") + openspace.toggleFade("Scene.StyxText.Renderable") ]], Documentation = "Toggles the visibility of the text labels of Pluto, Charon, Hydra, Nix, Kerberos, and Styx", GuiPath = "/Missions/New Horizons", @@ -196,12 +173,7 @@ local ToggleNewHorizonsLabels = { Identifier = "os.newhorizons.ToggleNewHorizonsLabels", Name = "Toggle New Horizons labels", Command = [[ - local v = openspace.propertyValue("Scene.Labels.Renderable.Opacity") - if v <= 0.5 then - openspace.setPropertyValueSingle("Scene.Labels.Renderable.Opacity", 1.0, 2.0) - else - openspace.setPropertyValueSingle("Scene.Labels.Renderable.Opacity", 0.0, 2.0) - end + openspace.toggleFade("Scene.Labels.Renderable") ]], Documentation = "Toggles the visibility of the labels for the New Horizons instruments", GuiPath = "/Missions/New Horizons", @@ -212,14 +184,8 @@ local ToggleShadows = { Identifier = "os.newhorizons.ToggleShadows", Name = "Toggle shadows", Command = [[ - openspace.setPropertyValueSingle( - "Scene.PlutoShadow.Renderable.Enabled", - not openspace.propertyValue("Scene.PlutoShadow.Renderable.Enabled") - ) - openspace.setPropertyValueSingle( - "Scene.CharonShadow.Renderable.Enabled", - not openspace.propertyValue("Scene.CharonShadow.Renderable.Enabled") - ) + openspace.toggleFade("Scene.PlutoShadow.Renderable") + openspace.toggleFade("Scene.CharonShadow.Renderable") ]], Documentation = "Toggles the visibility of the shadow visualization of Pluto and Charon", GuiPath = "/Missions/New Horizons", @@ -230,10 +196,7 @@ local ToggleNewHorizonsTrail = { Identifier = "os.newhorizons.ToggleNewHorizonsTrail", Name = "Toggle New Horizons trail", Command = [[ - openspace.setPropertyValueSingle( - "Scene.NewHorizonsTrailPluto.Renderable.Enabled", - not openspace.propertyValue("Scene.NewHorizonsTrailPluto.Renderable.Enabled") - ) + openspace.toggleFade("Scene.NewHorizonsTrailPluto.Renderable") ]], Documentation = "Toggles the trail of New Horizons", GuiPath = "/Missions/New Horizons", diff --git a/data/assets/scene/solarsystem/missions/newhorizons/charon.asset b/data/assets/scene/solarsystem/missions/newhorizons/charon.asset index dfd4699df4..c4148ff1ea 100644 --- a/data/assets/scene/solarsystem/missions/newhorizons/charon.asset +++ b/data/assets/scene/solarsystem/missions/newhorizons/charon.asset @@ -88,7 +88,8 @@ local CharonText = { }, GUI = { Name = "Charon Text", - Path = "/Solar System/Dwarf Planets/Pluto" + Path = "/Solar System/Dwarf Planets/Pluto", + Focusable = false } } @@ -107,7 +108,8 @@ local CharonShadow = { }, GUI = { Name = "Charon Shadow", - Path = "/Solar System/Dwarf Planets/Pluto" + Path = "/Solar System/Dwarf Planets/Pluto", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/newhorizons/dashboard.asset b/data/assets/scene/solarsystem/missions/newhorizons/dashboard.asset index 919c069a25..4c4d763297 100644 --- a/data/assets/scene/solarsystem/missions/newhorizons/dashboard.asset +++ b/data/assets/scene/solarsystem/missions/newhorizons/dashboard.asset @@ -15,9 +15,9 @@ local Distance = { Identifier = "NewHorizonsPlutoDistance", GuiName = "New Horizons Pluto Distance", SourceType = "Node", - SourceNodeName = "NewHorizons", + SourceNodeIdentifier = "NewHorizons", DestinationType = "Node Surface", - DestinationNodeName = "PlutoProjection" + DestinationNodeIdentifier = "PlutoProjection" } local Instruments = { diff --git a/data/assets/scene/solarsystem/missions/newhorizons/fov.asset b/data/assets/scene/solarsystem/missions/newhorizons/fov.asset index 149e8c4ec7..3581b23590 100644 --- a/data/assets/scene/solarsystem/missions/newhorizons/fov.asset +++ b/data/assets/scene/solarsystem/missions/newhorizons/fov.asset @@ -34,7 +34,8 @@ local Lorri = { }, GUI = { Name = "LORRI", - Path = "/Solar System/Missions/New Horizons/Instruments" + Path = "/Solar System/Missions/New Horizons/Instruments", + Focusable = false } } @@ -63,7 +64,8 @@ local RalphLeisa = { }, GUI = { Name = "RALPH LEISA", - Path = "/Solar System/Missions/New Horizons/Instruments" + Path = "/Solar System/Missions/New Horizons/Instruments", + Focusable = false } } @@ -92,7 +94,8 @@ local RalphMvicPan1 = { }, GUI = { Name = "RALPH MVIC PAN 1", - Path = "/Solar System/Missions/New Horizons/Instruments" + Path = "/Solar System/Missions/New Horizons/Instruments", + Focusable = false } } @@ -121,7 +124,8 @@ local RalphMvicPan2 = { }, GUI = { Name = "RALPH MVIC PAN 2", - Path = "/Solar System/Missions/New Horizons/Instruments" + Path = "/Solar System/Missions/New Horizons/Instruments", + Focusable = false } } @@ -150,7 +154,8 @@ local RalphMvicRed = { }, GUI = { Name = "RALPH MVIC RED", - Path = "/Solar System/Missions/New Horizons/Instruments" + Path = "/Solar System/Missions/New Horizons/Instruments", + Focusable = false } } @@ -179,7 +184,8 @@ local RalphMvicBlue = { }, GUI = { Name = "RALPH MVIC BLUE", - Path = "/Solar System/Missions/New Horizons/Instruments" + Path = "/Solar System/Missions/New Horizons/Instruments", + Focusable = false } } @@ -208,7 +214,8 @@ local RalphMvicFt = { }, GUI = { Name = "RALPH MVIC FT", - Path = "/Solar System/Missions/New Horizons/Instruments" + Path = "/Solar System/Missions/New Horizons/Instruments", + Focusable = false } } @@ -237,7 +244,8 @@ local RalphMvicMethane = { }, GUI = { Name = "RALPH MVIC METHANE", - Path = "/Solar System/Missions/New Horizons/Instruments" + Path = "/Solar System/Missions/New Horizons/Instruments", + Focusable = false } } @@ -266,7 +274,8 @@ local RalphMvicNir = { }, GUI = { Name = "RALPH MVIC NIR", - Path = "/Solar System/Missions/New Horizons/Instruments" + Path = "/Solar System/Missions/New Horizons/Instruments", + Focusable = false } } @@ -296,7 +305,8 @@ local AliceAirglow = { }, GUI = { Name = "ALICE AIRGLOW", - Path = "/Solar System/Missions/New Horizons/Instruments" + Path = "/Solar System/Missions/New Horizons/Instruments", + Focusable = false } } @@ -325,7 +335,8 @@ local AliceSoc = { }, GUI = { Name = "ALICE SOC", - Path = "/Solar System/Missions/New Horizons/Instruments" + Path = "/Solar System/Missions/New Horizons/Instruments", + Focusable = false } } @@ -354,7 +365,8 @@ local Rex = { }, GUI = { Name = "REX", - Path = "/Solar System/Missions/New Horizons/Instruments" + Path = "/Solar System/Missions/New Horizons/Instruments", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/newhorizons/horizons.asset b/data/assets/scene/solarsystem/missions/newhorizons/horizons.asset new file mode 100644 index 0000000000..d9a316d0cc --- /dev/null +++ b/data/assets/scene/solarsystem/missions/newhorizons/horizons.asset @@ -0,0 +1,62 @@ +local ssb = asset.require("scene/solarsystem/sun/transforms") + +local newhorizons_horizons = asset.resource({ + Name = "NewHorizons horizons", + Type = "HttpSynchronization", + Identifier = "newhorizons_horizons", + Version = 1 +}) + + +local NewHorizons = { + Identifier = "NewHorizons_Horizons", + Parent = ssb.SolarSystemBarycenter.Identifier, + Renderable = { + Type = "RenderableTrailTrajectory", + Enabled = false, + Translation = { + Type = "HorizonsTranslation", + HorizonsTextFile = newhorizons_horizons .. "newhorizons.hrz" + -- Target: New Horizons (spacecraft) (-98) + -- Observer: SSB + -- Start time: 2006-Jan-19 19:51:18.3310 (first data point) + -- End time: 2030-Jan-01 00:00:00 (last data point) + -- Step size: 1440 minutes + }, + Color = { 0.31, 0.71, 0.54 }, + LineFadeAmount = 0.3, + StartTime = "2006 JAN 19 19:51:19", + EndTime = "2030 JAN 01 00:00:00", + SampleInterval = openspace.time.secondsPerDay() + }, + GUI = { + Name = "New Horizons Trail (Horizons)", + Path = "/Solar System/Missions/New Horizons", + Focusable = false, + Description = [[New Horizons Trail, spanning from January 19th, 2006 to January 1st, + 2030. Data from JPL Horizons]] + } +} + + +asset.onInitialize(function() + openspace.addSceneGraphNode(NewHorizons) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(NewHorizons) +end) + +asset.export(NewHorizons) + + + +asset.meta = { + Name = "New Horizons Horizons Trails", + Description = [[New Horizons trail driven by JPL Horizons data for better performance + then SPICE but lower resolution. Data is from shortly after mission launch + until January 1st, 2030]], + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/scene/solarsystem/missions/newhorizons/label.asset b/data/assets/scene/solarsystem/missions/newhorizons/label.asset index b41125e178..5afd69abac 100644 --- a/data/assets/scene/solarsystem/missions/newhorizons/label.asset +++ b/data/assets/scene/solarsystem/missions/newhorizons/label.asset @@ -18,7 +18,8 @@ local Labels = { AmbientIntensity = 0.8 }, GUI = { - Path = "/Solar System/Missions/New Horizons" + Path = "/Solar System/Missions/New Horizons", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/newhorizons/othermoons.asset b/data/assets/scene/solarsystem/missions/newhorizons/othermoons.asset index 3c58d84824..0b9eae578b 100644 --- a/data/assets/scene/solarsystem/missions/newhorizons/othermoons.asset +++ b/data/assets/scene/solarsystem/missions/newhorizons/othermoons.asset @@ -53,7 +53,8 @@ local HydraText = { }, GUI = { Name = "Hydra Text", - Path = "/Solar System/Dwarf Planets/Pluto" + Path = "/Solar System/Dwarf Planets/Pluto", + Focusable = false } } @@ -76,7 +77,8 @@ local KerberosText = { }, GUI = { Name = "Kerberos Text", - Path = "/Solar System/Dwarf Planets/Pluto" + Path = "/Solar System/Dwarf Planets/Pluto", + Focusable = false } } @@ -93,7 +95,8 @@ local NixText = { }, GUI = { Name = "Nix Text", - Path = "/Solar System/Dwarf Planets/Pluto" + Path = "/Solar System/Dwarf Planets/Pluto", + Focusable = false } } @@ -116,7 +119,8 @@ local StyxText = { }, GUI = { Name = "Styx Text", - Path = "/Solar System/Dwarf Planets/Pluto" + Path = "/Solar System/Dwarf Planets/Pluto", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/newhorizons/pluto.asset b/data/assets/scene/solarsystem/missions/newhorizons/pluto.asset index 747fa0adfe..caa02d03d8 100644 --- a/data/assets/scene/solarsystem/missions/newhorizons/pluto.asset +++ b/data/assets/scene/solarsystem/missions/newhorizons/pluto.asset @@ -192,7 +192,8 @@ local PlutoBarycenterLabel = { }, GUI = { Name = "Pluto Barycenter Label", - Path = "/Solar System/Dwarf Planets/Pluto" + Path = "/Solar System/Dwarf Planets/Pluto", + Focusable = false } } @@ -215,7 +216,8 @@ local PlutoText = { }, GUI = { Name = "Pluto Text", - Path = "/Solar System/Dwarf Planets/Pluto" + Path = "/Solar System/Dwarf Planets/Pluto", + Focusable = false } } @@ -234,7 +236,8 @@ local PlutoShadow = { }, GUI = { Name = "Pluto Shadow", - Path = "/Solar System/Dwarf Planets/Pluto" + Path = "/Solar System/Dwarf Planets/Pluto", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/newhorizons/trail.asset b/data/assets/scene/solarsystem/missions/newhorizons/trail.asset index 6abb7c6966..05881d246c 100644 --- a/data/assets/scene/solarsystem/missions/newhorizons/trail.asset +++ b/data/assets/scene/solarsystem/missions/newhorizons/trail.asset @@ -25,7 +25,8 @@ local TrailAtPluto = { }, GUI = { Name = "New Horizons Trail Pluto", - Path = "/Solar System/Missions/New Horizons" + Path = "/Solar System/Missions/New Horizons", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/osirisrex/actions.asset b/data/assets/scene/solarsystem/missions/osirisrex/actions.asset index 09f90f1fca..c3cab44525 100644 --- a/data/assets/scene/solarsystem/missions/osirisrex/actions.asset +++ b/data/assets/scene/solarsystem/missions/osirisrex/actions.asset @@ -76,10 +76,7 @@ local ToggleSunMarker = { Identifier = "os.osirisrex.ToggleSunMarker", Name = "Toggle Sun marker", Command = [[ - openspace.setPropertyValueSingle( - "Scene.SunMarker.Renderable.Enabled", - not openspace.propertyValue("Scene.SunMarker.Renderable.Enabled") - ) + openspace.toggleFade("Scene.SunMarker.Renderable") ]], Documentation = "Toggles the visibility of the text marking the location of the Sun", GuiPath = "/Missions/Osiris Rex", diff --git a/data/assets/scene/solarsystem/missions/osirisrex/bennu_projection.asset b/data/assets/scene/solarsystem/missions/osirisrex/bennu_projection.asset index 2b7e392ea6..9805b2a6aa 100644 --- a/data/assets/scene/solarsystem/missions/osirisrex/bennu_projection.asset +++ b/data/assets/scene/solarsystem/missions/osirisrex/bennu_projection.asset @@ -105,7 +105,8 @@ local BennuTrail = { }, GUI = { Name = "Bennu Trail", - Path = "/Solar System/Asteroid" + Path = "/Solar System/Asteroid", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/osirisrex/dashboard.asset b/data/assets/scene/solarsystem/missions/osirisrex/dashboard.asset index 5427a98485..bbc027c8a5 100644 --- a/data/assets/scene/solarsystem/missions/osirisrex/dashboard.asset +++ b/data/assets/scene/solarsystem/missions/osirisrex/dashboard.asset @@ -15,9 +15,9 @@ local Distance = { Identifier = "OsirisRexBennuDistance", GuiName = "OSIRIS-REx Bennu Distance", SourceType = "Node", - SourceNodeName = model.OsirisRex.Identifier, + SourceNodeIdentifier = model.OsirisRex.Identifier, DestinationType = "Node", - DestinationNodeName = transforms.BennuBarycenter.Identifier + DestinationNodeIdentifier = transforms.BennuBarycenter.Identifier } local Instruments = { diff --git a/data/assets/scene/solarsystem/missions/osirisrex/mission.asset b/data/assets/scene/solarsystem/missions/osirisrex/mission.asset index d2d3e229d6..1b0179c55d 100644 --- a/data/assets/scene/solarsystem/missions/osirisrex/mission.asset +++ b/data/assets/scene/solarsystem/missions/osirisrex/mission.asset @@ -33,13 +33,13 @@ local Mission = { Identifier = "OsirisRex", Name = "OSIRIS-REx", Description = "Launched on Sept. 8, 2016, the Origins, Spectral Interpretation, Resource Identification, Security-Regolith Explorer (OSIRIS-REx) spacecraft traveled to a near-Earth asteroid called Bennu (formerly 1999 RQ36), and collected a sample of the of rocks and material from the surface that it will return to Earth in 2023. The mission will help scientists investigate how planets formed and how life began, as well as improve our understanding of asteroids that could impact Earth.", - Image = "https://www.nasa.gov/sites/default/files/styles/full_width_feature/public/thumbnails/image/osiris-rex-mission-logo12_copy.png", + Image = "https://data.openspaceproject.com/missions/osirisrex/osiris-rex-mission-logo12-copy.png", Actions = { "os.osirisrex.AimAtBennu", "os.osirisrex.SetLaunchTime", "os.osirisrex.LookImageCapture" }, Phases = { -- All 1-level phases based on [1] { Name = "Outbound Cruise", - Image = "https://www.nasa.gov/sites/default/files/styles/full_width_feature/public/thumbnails/image/28929096574_85a647dc8e_o.jpg", + Image = "https://data.openspaceproject.com/missions/osirisrex/OSIRIS-REx_launch_28929096574_85a647dc8e_o.jpg", Phases = { -- Phases from [4] { @@ -56,7 +56,7 @@ local Mission = { { Name = "Solar Orbit", TimeRange = { Start = "2016 SEP 08 23:45:00", End = "2018 SEP 01 00:00:00" }, - Image = "https://www.nasa.gov/sites/default/files/styles/full_width_feature/public/thumbnails/image/ega_1ms_mapcam_color_corrected_0.png", + Image = "https://data.openspaceproject.com/missions/osirisrex/ega_1ms_mapcam_color_corrected_0.png", Description = "A color composite image of Earth taken on Sept. 22 by the MapCam camera on NASA's OSIRIS-REx spacecraft. This image was taken just hours after the spacecraft completed its Earth Gravity Assist at a range of approximately 106,000 miles (170,000 kilometers). MapCam is part of the OSIRIS-REx Camera Suite (OCAMS) operated by the University of Arizona. Visible in this image are the Pacific Ocean and several familiar landmasses, including Australia in the lower left, and Baja California and the southwestern United States in the upper right. The dark vertical streaks at the top of the image are caused by short exposure times (less than three milliseconds). Short exposure times are required for imaging an object as bright as Earth, but are not anticipated for an object as dark as the asteroid Bennu, which the camera was designed to image. Date Taken: Sept. 22, 2017", Phases = { { @@ -77,13 +77,13 @@ local Mission = { Name = "Approach", Description = "Approach Phase began on August 17, 2018, when the spacecraft was still about 1.2 million miles (two million km) away from Bennu, and it continued until the spacecraft arrived at the asteroid on December 3, 2018. The primary goals of Approach were to visually locate Bennu for the first time, survey the surrounding area for potential hazards, and collect enough imagery of Bennu for scientists to generate a detailed shape model of the asteroid, assign a coordinate system, and understand its spin state.", TimeRange = { Start = "2018-AUG-17 00:00:00.000", End = "2018-DEC-31 01:34:21.183" }, - Image = "https://www.nasa.gov/sites/default/files/styles/full_width_feature/public/thumbnails/image/lbt-orex-1049-loop-gif.gif", + Image = "https://data.openspaceproject.com/missions/osirisrex/LBT-OREx-1049-loop-gif-1.gif", Phases = { { Name = "Dust Plume Search Observation", Description = "Search for dust and gas plumes originating from the asteroid surface, and characterize their source regions and column densities. Information on the presence and location of dust and gas plumes is needed to assess safety, understand the geologic and dynamic history of the asteroid, and inform sample-site selection.", TimeRange = { Start = "2018-SEP-11 21:31:01.183", End = "2018-SEP-12 02:18:41.183" }, - Image = "https://www.asteroidmission.org/wp-content/uploads/2018/09/MapCamDustSearch-1.jpg" + Image = "https://data.openspaceproject.com/missions/osirisrex/MapCamDustSearch-1.jpg" }, { Name = "Light Curve", @@ -114,7 +114,7 @@ local Mission = { { Name = "Preliminary Survey", Description = "Preliminary Survey Phase began with the spacecraft's arrival at Bennu on December 3, 2018, and marked the first time that the OSIRIS-REx spacecraft operated around the asteroid. The spacecraft made a total of five passes over the north pole, equator, and south pole at a range of 4.3 miles (7 km). The primary science goals of Preliminary Survey were to estimate Bennu's mass, refine the asteroid's spin state model, and generate a global shape model at a resolution of 75-cm.", - Image = "https://www.asteroidmission.org/wp-content/uploads/2018/05/Prelim-Survey-for-Web.jpg", + Image = "https://data.openspaceproject.com/missions/osirisrex/Prelim-Survey-for-Web.jpg", Phases = { { Name = "MapCamOLA Phase 1", @@ -222,7 +222,7 @@ local Mission = { { Name = "Orbital B", Description = "At the end of Detailed Survey, the spacecraft entered a close orbit - with a radius of 0.6 miles (1 km) - around Bennu to begin Orbital B Phase. This phase broke the record OSIRIS-REx set in Orbital A for the closest that a spacecraft has ever orbited around a small body. The primary science activities for this phase were the global mapping of Bennu, the development of shape modeling based on OLA data, and the execution of a Radio Science experiment. These data were used to evaluate potential sample collection sites for three key elements: safety, sampleability and science value. Orbital B concluded with the team narrowing in on a primary and a back-up sample site.", - Image = "https://www.asteroidmission.org/wp-content/uploads/2018/05/Orbital-B-for-Web.jpg", + Image = "https://data.openspaceproject.com/missions/osirisrex/Orbital-B-for-Web.jpg", Phases = { { Name = "Candidate Sample Site Phase 1", diff --git a/data/assets/scene/solarsystem/missions/osirisrex/model.asset b/data/assets/scene/solarsystem/missions/osirisrex/model.asset index 647eea7f94..2fbddafc35 100644 --- a/data/assets/scene/solarsystem/missions/osirisrex/model.asset +++ b/data/assets/scene/solarsystem/missions/osirisrex/model.asset @@ -131,7 +131,8 @@ local PolyCamFov = { }, GUI = { Name = "POLYCAM FOV", - Path = "/Solar System/Missions/OSIRIS REx/Instruments" + Path = "/Solar System/Missions/OSIRIS REx/Instruments", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/osirisrex/trail.asset b/data/assets/scene/solarsystem/missions/osirisrex/trail.asset index e3502cedd8..e608699176 100644 --- a/data/assets/scene/solarsystem/missions/osirisrex/trail.asset +++ b/data/assets/scene/solarsystem/missions/osirisrex/trail.asset @@ -24,7 +24,8 @@ local OsirisRexTrailEarth = { }, GUI = { Name = "OSIRIS REx Trail Earth", - Path = "/Solar System/Missions/OSIRIS REx" + Path = "/Solar System/Missions/OSIRIS REx", + Focusable = false } } @@ -45,7 +46,8 @@ local OsirisRexTrailSolarSystem = { }, GUI = { Name = "OSIRIS REx Trail Solar System", - Path = "/Solar System/Missions/OSIRIS REx" + Path = "/Solar System/Missions/OSIRIS REx", + Focusable = false } } @@ -66,7 +68,8 @@ local OsirisRexTrailBennu = { }, GUI = { Name = "OSIRIS REx Trail Bennu", - Path = "/Solar System/Missions/OSIRIS REx" + Path = "/Solar System/Missions/OSIRIS REx", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/perseverance/mission.asset b/data/assets/scene/solarsystem/missions/perseverance/mission.asset index db45229dae..efe0684c94 100644 --- a/data/assets/scene/solarsystem/missions/perseverance/mission.asset +++ b/data/assets/scene/solarsystem/missions/perseverance/mission.asset @@ -5,22 +5,22 @@ local Mission = { { Name = "First Color Photo", TimeRange = { Start = "2021 FEB 18" }, - Image = "http://data.openspaceproject.com/missions/perseverance/Perseverance's_First_Full-Color_Look_at_Mars.png" + Image = "https://data.openspaceproject.com/missions/perseverance/Perseverance's_First_Full-Color_Look_at_Mars.png" }, { Name = "First Study Target", TimeRange = { Start = "2021 FEB 22" }, - Image = "http://data.openspaceproject.com/missions/perseverance/PIA24484-MarsPerseveranceRover-FirstStudyTarget-20210222.jpg" + Image = "https://data.openspaceproject.com/missions/perseverance/PIA24484-MarsPerseveranceRover-FirstStudyTarget-20210222.jpg" }, { Name = "Drive Test", TimeRange = { Start = "2021 MAR 07" }, - Image = "http://data.openspaceproject.com/missions/perseverance/PIA23729-MarsPerseveranceRover-DriveTest-20210307.jpg" + Image = "https://data.openspaceproject.com/missions/perseverance/PIA23729-MarsPerseveranceRover-DriveTest-20210307.jpg" }, { Name = "Ingenuity Helicopter launch", TimeRange = { Start = "2021 APR 04" }, - Image = "http://data.openspaceproject.com/missions/perseverance/Ingenuity_helicopter_first_colour_image.jpg" + Image = "https://data.openspaceproject.com/missions/perseverance/Ingenuity_helicopter_first_colour_image.jpg" }, { Name = "Ingenuity Helicopter First Flight", diff --git a/data/assets/scene/solarsystem/missions/perseverance/model.asset b/data/assets/scene/solarsystem/missions/perseverance/model.asset index 36a73de73a..e2f76b1f26 100644 --- a/data/assets/scene/solarsystem/missions/perseverance/model.asset +++ b/data/assets/scene/solarsystem/missions/perseverance/model.asset @@ -74,6 +74,7 @@ local PerseveranceNode = { GUI = { Name = "Perseverance Node", Path = "/Solar System/Missions/Perseverance", + Focusable = false, Hidden = true } } @@ -101,6 +102,7 @@ local PerseveranceModel = { GUI = { Name = "Perseverance Model", Path = "/Solar System/Missions/Perseverance", + Focusable = false, Hidden = true } } diff --git a/data/assets/scene/solarsystem/missions/perseverance/trail.asset b/data/assets/scene/solarsystem/missions/perseverance/trail.asset index 97d4c232d8..9fe9fba9d2 100644 --- a/data/assets/scene/solarsystem/missions/perseverance/trail.asset +++ b/data/assets/scene/solarsystem/missions/perseverance/trail.asset @@ -27,7 +27,8 @@ local PerseveranceTrailSun = { }, GUI = { Name = "Perseverance Trail (Sun)", - Path = "/Solar System/Missions/Perseverance" + Path = "/Solar System/Missions/Perseverance", + Focusable = false } } @@ -49,7 +50,8 @@ local PerseveranceTrailMars = { }, GUI = { Name = "Perseverance Trail (Mars)", - Path = "/Solar System/Missions/Perseverance" + Path = "/Solar System/Missions/Perseverance", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/pioneer/horizons.asset b/data/assets/scene/solarsystem/missions/pioneer/horizons.asset new file mode 100644 index 0000000000..6e09394afa --- /dev/null +++ b/data/assets/scene/solarsystem/missions/pioneer/horizons.asset @@ -0,0 +1,95 @@ +local ssb = asset.require("scene/solarsystem/sun/transforms") + +local pioneer_horizons = asset.resource({ + Name = "Pioneer horizons", + Type = "HttpSynchronization", + Identifier = "pioneer_horizons", + Version = 1 +}) + + +local Pioneer10 = { + Identifier = "Pioneer10_Horizons", + Parent = ssb.SolarSystemBarycenter.Identifier, + Renderable = { + Type = "RenderableTrailTrajectory", + Enabled = false, + Translation = { + Type = "HorizonsTranslation", + HorizonsTextFile = pioneer_horizons .. "pioneer_10.hrz" + -- Target: Pioneer 10 (spacecraft) (-23) + -- Observer: SSB + -- Start time: 1972-Mar-04 00:00:00 (first data point) + -- End time: 2030-Jan-01 00:00:00 (last data point) + -- Step size: 1 day + }, + Color = { 0.9, 0.3, 0.0 }, + Fade = 5.0, + StartTime = "1972 MAR 04 00:00:00", + EndTime = "2030 JAN 01 00:00:00", + SampleInterval = openspace.time.secondsPerDay() + }, + GUI = { + Name = "Pioneer 10 Trail (Horizons)", + Path = "/Solar System/Missions/Pioneer", + Focusable = false, + Description = [[Pioneer 10 Trail, spanning from March 4th, 1972 to January 1st, 2030. + Data from JPL Horizons]] + } +} + +local Pioneer11 = { + Identifier = "Pioneer11_Horizons", + Parent = ssb.SolarSystemBarycenter.Identifier, + Renderable = { + Type = "RenderableTrailTrajectory", + Enabled = false, + Translation = { + Type = "HorizonsTranslation", + HorizonsTextFile = pioneer_horizons .. "pioneer_11.hrz" + -- Target: Pioneer 11 (spacecraft) (-24) + -- Observer: SSB + -- Start time: 1973-Apr-07 00:00:00 (first data point) + -- End time: 2030-Jan-01 00:00:00 (last data point) + -- Step size: 1 day + }, + Color = { 0.9, 0.3, 0.0 }, + LineFadeAmount = 0.3, + StartTime = "1973 APR 07 00:00:00", + EndTime = "2030 JAN 01 00:00:00", + SampleInterval = openspace.time.secondsPerDay() + }, + GUI = { + Name = "Pioneer 11 Trail (Horizons)", + Path = "/Solar System/Missions/Pioneer", + Focusable = false, + Description = [[Pioneer 11 Trail, spanning from April 7th, 1973 to January 1st, 2030. + Data from JPL Horizons]] + } +} + + +asset.onInitialize(function() + openspace.addSceneGraphNode(Pioneer10) + openspace.addSceneGraphNode(Pioneer11) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(Pioneer11) + openspace.removeSceneGraphNode(Pioneer10) +end) + +asset.export(Pioneer10) +asset.export(Pioneer11) + + + +asset.meta = { + Name = "Pioneer Horizons Trails", + Description = [[Pioneer 10, Pioneer 11 trails driven by JPL Horizons data for better + performance then SPICE but lower resolution. Data is from shortly after mission + launches until January 1st, 2030]], + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/scene/solarsystem/missions/pioneer/pioneer10.asset b/data/assets/scene/solarsystem/missions/pioneer/pioneer10.asset index 57ed722850..e0769dfc65 100644 --- a/data/assets/scene/solarsystem/missions/pioneer/pioneer10.asset +++ b/data/assets/scene/solarsystem/missions/pioneer/pioneer10.asset @@ -50,6 +50,7 @@ local Pioneer10Trail = { GUI = { Name = "Pioneer 10 Trail (SPICE)", Path = "/Solar System/Missions/Pioneer", + Focusable = false, Description = [[Pioneer 10 Trail, spanning March 3rd, 1972 to January 2nd, 1990. Data from SPICE]] } diff --git a/data/assets/scene/solarsystem/missions/pioneer/pioneer11.asset b/data/assets/scene/solarsystem/missions/pioneer/pioneer11.asset index 4db1484673..ecee70721d 100644 --- a/data/assets/scene/solarsystem/missions/pioneer/pioneer11.asset +++ b/data/assets/scene/solarsystem/missions/pioneer/pioneer11.asset @@ -55,6 +55,7 @@ local Pioneer11Trail = { GUI = { Name = "Pioneer 11 Trail (SPICE)", Path = "/Solar System/Missions/Pioneer", + Focusable = false, Description = [[Pioneer 11 Trail, spanning April 6th, 1973 to January 2nd, 1990. Data from SPICE]] } diff --git a/data/assets/scene/solarsystem/missions/rosetta/67p.asset b/data/assets/scene/solarsystem/missions/rosetta/67p.asset index 27c0dafd75..f8a6a68125 100644 --- a/data/assets/scene/solarsystem/missions/rosetta/67p.asset +++ b/data/assets/scene/solarsystem/missions/rosetta/67p.asset @@ -133,7 +133,8 @@ local Trail67P = { }, GUI = { Name = "67P Trail", - Path = "/Solar System/Comets/67P Churymov-Gerasimenko" + Path = "/Solar System/Comets/67P Churymov-Gerasimenko", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/rosetta/actions.asset b/data/assets/scene/solarsystem/missions/rosetta/actions.asset index 81b11f4dfb..aac83acb2f 100644 --- a/data/assets/scene/solarsystem/missions/rosetta/actions.asset +++ b/data/assets/scene/solarsystem/missions/rosetta/actions.asset @@ -1,12 +1,7 @@ local ToggleOuterPlanetaryTrails = { Identifier = "os.rosetta.ToggleOuterPlanetaryTrails", Name = "Toggle outer planetary trails", - Command = [[ - local list = openspace.property("{planetTrail_giants}.Renderable.Enabled") - for _,v in pairs(list) do - openspace.setPropertyValueSingle(v, not openspace.propertyValue(v)) - end - ]], + Command = [[openspace.toggleFade("{planetTrail_giants}.Renderable")]], Documentation = "Toggles the visibility of all trails further from the Sun than 67P", GuiPath = "/Missions/Rosetta", IsLocal = false diff --git a/data/assets/scene/solarsystem/missions/rosetta/dashboard.asset b/data/assets/scene/solarsystem/missions/rosetta/dashboard.asset index 6091b75d85..41aecc2271 100644 --- a/data/assets/scene/solarsystem/missions/rosetta/dashboard.asset +++ b/data/assets/scene/solarsystem/missions/rosetta/dashboard.asset @@ -15,9 +15,9 @@ local Distance = { Identifier = "Rosetta67PDistance", GuiName = "Rosetta 67P Distance", SourceType = "Node", - SourceNodeName = rosetta.Rosetta.Identifier, + SourceNodeIdentifier = rosetta.Rosetta.Identifier, DestinationType = "Node", - DestinationNodeName = cg.Comet67P.Identifier + DestinationNodeIdentifier = cg.Comet67P.Identifier } local Instruments = { diff --git a/data/assets/scene/solarsystem/missions/rosetta/mission.asset b/data/assets/scene/solarsystem/missions/rosetta/mission.asset index 3ee1cbb585..3e1f1c2cdc 100644 --- a/data/assets/scene/solarsystem/missions/rosetta/mission.asset +++ b/data/assets/scene/solarsystem/missions/rosetta/mission.asset @@ -4,7 +4,7 @@ local Mission = { Identifier = "Rosetta", Name = "Rosetta", TimeRange = { Start = "2004 MAR 02 00:00:00", End = "2016 SEP 30 00:00:00" }, - Image = "https://www.cosmos.esa.int/documents/522118/522182/Rosetta_logo.png/cd85878d-2fac-e086-e32a-df0eaee5e505?t=1614026031720", + Image = "https://data.openspaceproject.com/missions/rosetta/Rosetta_logo.png", Description = "ESAs Rosetta mission was the first to rendezvous with a comet, the first to follow a comet on its orbit around the Sun, and the first to deploy a lander to a comets surface. Comets are time capsules containing primitive material left over from the epoch when the Sun and its planets formed. By studying the gas, dust and structure of the nucleus and organic materials associated with the comet, via both remote and in situ observations, the Rosetta mission is unlocking the history and evolution of our Solar System.", Milestones = { { @@ -14,15 +14,14 @@ local Mission = { { Name = "First Earth gravity assist", Date = "2005 MAR 04 00:00:00", - Image = "https://www.esa.int/var/esa/storage/images/esa_multimedia/images/2005/03/moonrise_above_the_pacific_22_06_utc_4_march_2005/9520996-4-eng-GB/Moonrise_above_the_Pacific_22_06_UTC_4_March_2005_pillars.jpg", - Description = "The Moon rising above the Pacific, three minutes before the point of closest approach during Rosettas first Earth fly-by.", - Link = "https://www.esa.int/var/esa/storage/images/esa_multimedia/images/2015/08/approaching_perihelion_animation/15556093-1-eng-GB/Approaching_perihelion_Animation_pillars.gif" + Image = "https://data.openspaceproject.com/missions/rosetta/Moonrise_above_the_Pacific_22_06_UTC_4_March_2005_pillars.jpg", + Description = "The Moon rising above the Pacific, three minutes before the point of closest approach during Rosettas first Earth fly-by." }, { Name = "Mars gravity assist", Date = "2007 FEB 25 00:00:00", Description = "The Rosetta swing-by of Mars is the second of four gravity assists needed to place Rosetta on course for its final destination: comet 67P/Churyumov-Gerasimenko. The closest approach of the swing-by will take place at 01:54 UT, when the spacecraft will pass 250 km above the surface of Mars.", - Image = "https://www.esa.int/var/esa/storage/images/esa_multimedia/images/2007/02/image_of_mars_seen_by_osiris/10287257-2-eng-GB/Image_of_Mars_seen_by_OSIRIS_pillars.jpg", + Image = "https://data.openspaceproject.com/missions/rosetta/Image_of_Mars_seen_by_OSIRIS_pillars.jpg", Link = "https://sci.esa.int/web/rosetta/-/40697-rosetta-mars-swing-by" }, { @@ -33,7 +32,7 @@ local Mission = { { Name = "Asteroid Steins flyby", Date = "2008 SEP 05 00:00:00", - Image = "https://cdn.sci.esa.int/documents/34878/35534/1567217294466-Steins-FlyBy-Mosaic_625.jpg", + Image = "https://data.openspaceproject.com/missions/rosetta/1567217294466-Steins-FlyBy-Mosaic_625.jpg", Description = "Images of asteroid 2867-Steins taken by the OSIRIS Wide Angle Camera during the fly-by of 5 September 2008. The effective diameter of the asteroid is 5 km, approximately as predicted. At the top of the asteroid, a large crater, approximately 2 km in size, can be seen." }, { @@ -43,7 +42,7 @@ local Mission = { { Name = "Asteroid Lutetia flyby", Date = "2010 NOV 10 00:00:00", - Image = "https://cdn.sci.esa.int/documents/34878/35534/1567216468815-4_closest_approach-0_625.jpg", + Image = "https://data.openspaceproject.com/missions/rosetta/1567216468815-4_closest_approach-0_625.jpg", Description = "Together with 2867-Steins, 21-Lutetia is one of the two target asteroids that Rosetta will study during its long trek to comet 67P-Churyumov-Gersimenko." }, { @@ -53,7 +52,7 @@ local Mission = { { Name = "Arrive at comet", Date = "2014 AUG 06 00:00:00", - Image = "https://www.esa.int/var/esa/storage/images/esa_multimedia/images/2014/08/navcam_animation_6_august/14705553-1-eng-GB/NavCam_animation_6_August_pillars.gif", + Image = "https://data.openspaceproject.com/missions/rosetta/NavCam_animation_6_August_pillars.gif", Description = "After ten years, five months and four days travelling towards our destination, looping around the Sun five times and clocking up 6.4 billion kilometres, we are delighted to announce finally we are here, exclaimed Jean-Jacques Dordain, ESA's Director General." }, { @@ -64,14 +63,14 @@ local Mission = { { Name = "Philae lander delivery", Date = "2014 NOV 12 00:00:00", - Image = "https://cdn.sci.esa.int/documents/34878/35534/1567216603810-ESA_Rosetta_OSIRIS_NAC_Farewell_Philae_625.jpg", + Image = "https://data.openspaceproject.com/missions/rosetta/1567216603810-ESA_Rosetta_OSIRIS_NAC_Farewell_Philae_625.jpg", Description = "Rosetta's OSIRIS narrow-angle camera captured this parting shot of the Philae lander after separation." }, { Name = "Closest approach to Sun (Perihelion)", Date = "2015 AUG 13 00:00:00", Description = "Perihelion is the closest point a Solar System object gets to the Sun along its orbit (aphelion is the term given to the most distant point).", - Image = "https://www.esa.int/var/esa/storage/images/esa_multimedia/images/2015/03/comet_s_orbit/15317969-1-eng-GB/Comet_s_orbit_pillars.jpg" + Image = "https://data.openspaceproject.com/missions/rosetta/Comet_s_orbit_pillars.jpg" }, { Name = "Mission end", @@ -100,8 +99,7 @@ local Mission = { }, { Name = "Mission", - Image = "https://www.esa.int/var/esa/storage/images/esa_multimedia/images/2015/08/approaching_perihelion_animation/15556093-1-eng-GB/Approaching_perihelion_Animation_pillars.gif", - Link = "https://www.esa.int/var/esa/storage/images/esa_multimedia/images/2015/08/approaching_perihelion_animation/15556093-1-eng-GB/Approaching_perihelion_Animation_pillars.gif", + Image = "https://data.openspaceproject.com/missions/rosetta/Approaching_perihelion_Animation_pillars.gif", Description = "At 10:00 CET the spacecraft woke up and started post-hibernation procedures, including communications with ESA and NASA.", TimeRange = { Start = "2014 JAN 20 10:00:00", End = "2016 SEP 30 00:00:00" } } diff --git a/data/assets/scene/solarsystem/missions/rosetta/rosetta.asset b/data/assets/scene/solarsystem/missions/rosetta/rosetta.asset index cd03949867..dbf024975e 100644 --- a/data/assets/scene/solarsystem/missions/rosetta/rosetta.asset +++ b/data/assets/scene/solarsystem/missions/rosetta/rosetta.asset @@ -94,6 +94,7 @@ local PhilaePosition = { GUI = { Name = "Philae Position", Path = "/Solar System/Missions/Rosetta", + Focusable = false, Hidden = true } } @@ -126,7 +127,8 @@ local Philae = { }, GUI = { Name = "Philae", - Path = "/Solar System/Missions/Rosetta" + Path = "/Solar System/Missions/Rosetta", + Focusable = false } } @@ -134,7 +136,8 @@ local NavCam = { Identifier = "NAVCAM", Parent = RosettaPosition.Identifier, GUI = { - Path = "/Solar System/Missions/Rosetta/Instruments" + Path = "/Solar System/Missions/Rosetta/Instruments", + Focusable = false } } @@ -158,7 +161,8 @@ local NavCamFov = { }, GUI = { Name = "NAVCAM FOV", - Path = "/Solar System/Missions/Rosetta/Instruments" + Path = "/Solar System/Missions/Rosetta/Instruments", + Focusable = false } } @@ -197,7 +201,8 @@ local RosettaCometTrail = { }, GUI = { Name = "Rosetta Comet Trail", - Path = "/Solar System/Missions/Rosetta" + Path = "/Solar System/Missions/Rosetta", + Focusable = false } } @@ -218,7 +223,8 @@ local PhilaeTrail = { }, GUI = { Name = "Philae Trail", - Path = "/Solar System/Missions/Rosetta" + Path = "/Solar System/Missions/Rosetta", + Focusable = false } } @@ -250,10 +256,7 @@ local ToggleImagePlane = { Identifier = "os.rosetta.ToggleImagePlane", Name = "Toggle image plane", Command = [[ - openspace.setPropertyValueSingle( - "Scene.ImagePlaneRosetta.Renderable.Enabled", - not openspace.propertyValue("Scene.ImagePlaneRosetta.Renderable.Enabled") - ) + openspace.toggleFade("Scene.ImagePlaneRosetta.Renderable") ]], Documentation = "Toggles the visibility of the free floating image plane", GuiPath = "/Missions/Rosetta", @@ -264,10 +267,7 @@ local TogglePhilaeTrail = { Identifier = "os.rosetta.TogglePhilaeTrail", Name = "Toggle Philae trail", Command = [[ - openspace.setPropertyValueSingle( - "Scene.PhilaeTrail.Renderable.Enabled", - not openspace.propertyValue("Scene.PhilaeTrail.Renderable.Enabled") - ) + openspace.toggleFade("Scene.PhilaeTrail.Renderable") ]], Documentation = "Toggles the visibility of Philae's trail", GuiPath = "/Missions/Rosetta", diff --git a/data/assets/scene/solarsystem/missions/voyager/actions.asset b/data/assets/scene/solarsystem/missions/voyager/actions.asset index 293e1d8abb..c770326132 100644 --- a/data/assets/scene/solarsystem/missions/voyager/actions.asset +++ b/data/assets/scene/solarsystem/missions/voyager/actions.asset @@ -49,12 +49,7 @@ local SaturnFocus = { local ToggleMinorMoonTrails = { Identifier = "os.voyager.ToggleMinorMoonTrails", Name = "Toggle minor trails", - Command = [[ - local list = openspace.property("{moonTrail_minor}.Renderable.Enabled") - for _,v in pairs(list) do - openspace.setPropertyValueSingle(v, not openspace.propertyValue(v)) - end - ]], + Command = [[openspace.toggleFade("{moonTrail_minor}.Renderable")]], Documentation = "Toggles the trails of the minor moons", GuiPath = "/Trails", IsLocal = false diff --git a/data/assets/scene/solarsystem/missions/voyager/dashboard.asset b/data/assets/scene/solarsystem/missions/voyager/dashboard.asset index 64ab43fa87..3a3c21e029 100644 --- a/data/assets/scene/solarsystem/missions/voyager/dashboard.asset +++ b/data/assets/scene/solarsystem/missions/voyager/dashboard.asset @@ -8,9 +8,9 @@ local DistanceVoyager1 = { Identifier = "Voyager1Distance", GuiName = "Voyager 1 - Earth Distance", SourceType = "Node", - SourceNodeName = voyager1.Voyager_1.Identifier, + SourceNodeIdentifier = voyager1.Voyager_1.Identifier, DestinationType = "Node", - DestinationNodeName = earth.Earth.Identifier, + DestinationNodeIdentifier = earth.Earth.Identifier, Enabled = asset.enabled } @@ -19,9 +19,9 @@ local DistanceVoyager2 = { Identifier = "Voyager2Distance", GuiName = "Voyager 2 - Earth Distance", SourceType = "Node", - SourceNodeName = voyager2.Voyager_2.Identifier, + SourceNodeIdentifier = voyager2.Voyager_2.Identifier, DestinationType = "Node", - DestinationNodeName = earth.Earth.Identifier, + DestinationNodeIdentifier = earth.Earth.Identifier, Enabled = asset.enabled } diff --git a/data/assets/scene/solarsystem/missions/voyager/horizons.asset b/data/assets/scene/solarsystem/missions/voyager/horizons.asset new file mode 100644 index 0000000000..b02031f419 --- /dev/null +++ b/data/assets/scene/solarsystem/missions/voyager/horizons.asset @@ -0,0 +1,95 @@ +local ssb = asset.require("scene/solarsystem/sun/transforms") + +local voyager_horizons = asset.resource({ + Name = "Voyager horizons", + Type = "HttpSynchronization", + Identifier = "voyager_horizons", + Version = 1 +}) + + +local Voyager1 = { + Identifier = "Voyager1_Horizons", + Parent = ssb.SolarSystemBarycenter.Identifier, + Renderable = { + Type = "RenderableTrailTrajectory", + Enabled = false, + Translation = { + Type = "HorizonsTranslation", + HorizonsTextFile = voyager_horizons .. "voyager_1.hrz" + -- Target: Voyager 1 (spacecraft) (-31) + -- Observer: SSB + -- Start time: 1977-Sep-06 00:00:00 (first data point) + -- End time: 2030-Jan-01 00:00:00 (last data point) + -- Step size: 1 day + }, + Color = { 0.9, 0.9, 0.0 }, + Fade = 5.0, + StartTime = "1977 SEP 06 00:00:00", + EndTime = "2030 JAN 01 00:00:00", + SampleInterval = openspace.time.secondsPerDay() + }, + GUI = { + Name = "Voyager 1 Trail (Horizons)", + Path = "/Solar System/Missions/Voyager", + Focusable = false, + Description = [[Voyager 1 Trail, spanning from September 6th, 1977 to January 1st, + 2030. Data from JPL Horizons]] + } +} + +local Voyager2 = { + Identifier = "Voyager2_Horizons", + Parent = ssb.SolarSystemBarycenter.Identifier, + Renderable = { + Type = "RenderableTrailTrajectory", + Enabled = false, + Translation = { + Type = "HorizonsTranslation", + HorizonsTextFile = voyager_horizons .. "voyager_2.hrz" + -- Target: Voyager 2 (spacecraft) (-32) + -- Observer: SSB + -- Start time: 1977-Aug-21 00:00:00 (first data point) + -- End time: 2030-Jan-01 00:00:00 (last data point) + -- Step size: 1 day + }, + Color = { 0.9, 0.9, 0.0 }, + LineFadeAmount = 0.3, + StartTime = "1977 AUG 21 00:00:00", + EndTime = "2030 JAN 01 00:00:00", + SampleInterval = openspace.time.secondsPerDay() + }, + GUI = { + Name = "Voyager 2 Trail (Horizons)", + Path = "/Solar System/Missions/Voyager", + Focusable = false, + Description = [[Voyager 2 Trail, spanning from August 21st, 1977 to January 1st, 2030. + Data from JPL Horizons]] + } +} + + +asset.onInitialize(function() + openspace.addSceneGraphNode(Voyager1) + openspace.addSceneGraphNode(Voyager2) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(Voyager2) + openspace.removeSceneGraphNode(Voyager1) +end) + +asset.export(Voyager1) +asset.export(Voyager2) + + + +asset.meta = { + Name = "Voyager Horizons Trails", + Description = [[Voyager 1 and Voyager 2 trails driven by JPL Horizons data for better + performance then SPICE but lower resolution. Data is from shortly after mission + launches until January 1st, 2030]], + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/scene/solarsystem/missions/voyager/mission.asset b/data/assets/scene/solarsystem/missions/voyager/mission.asset index 23b712834d..c28a4501aa 100644 --- a/data/assets/scene/solarsystem/missions/voyager/mission.asset +++ b/data/assets/scene/solarsystem/missions/voyager/mission.asset @@ -7,42 +7,42 @@ local Mission = { Identifier = "Voyager", Name = "Voyager", - Image = "https://upload.wikimedia.org/wikipedia/commons/8/87/Voyager_-_mission_logo.png", + Image = "https://data.openspaceproject.com/missions/voyager/Voyager_-_mission_logo.png", Description = "The twin Voyager 1 and 2 spacecraft are exploring where nothing from Earth has flown before. Continuing on their more-than-40-year journey since their 1977 launches, they each are much farther away from Earth and the sun than Pluto. In August 2012, Voyager 1 made the historic entry into interstellar space, the region between stars, filled with material ejected by the death of nearby stars millions of years ago. Voyager 2 entered interstellar space on November 5, 2018 and scientists hope to learn more about this region. Both spacecraft are still sending scientific information about their surroundings through the Deep Space Network, or DSN. The primary mission was the exploration of Jupiter and Saturn. After making a string of discoveries there — such as active volcanoes on Jupiter's moon Io and intricacies of Saturn's rings — the mission was extended. Voyager 2 went on to explore Uranus and Neptune, and is still the only spacecraft to have visited those outer planets. The adventurers' current mission, the Voyager Interstellar Mission (VIM), will explore the outermost edge of the Sun's domain. And beyond.", Milestones = { { Name = "Voyager 1 Jupiter Encounter", Date = "1979 MAR 05 00:00:00", Description = "Voyager 1 discovered a thin ring around Jupiter and two new Jovian moons: Thebe and Metis.", - Image = "https://voyager.jpl.nasa.gov/assets/images/galleries/approaches/jupiter2.gif" + Image = "https://data.openspaceproject.com/missions/voyager/jupiter2.gif" }, { Name = "Voyager 2 Jupiter Encounter", Date = "1979 JUL 09 00:00:00", Description = "During the Jupiter leg of its journey, Voyager 2 explored the giant planet, its magnetosphere and moons in greater detail than had the Pioneer spacecraft that preceded it. Voyager 2 also used it as a springboard to Saturn, using the gravity-assist technique. Voyager 2 succeeded on all counts. It returned spectacular photos of the entire Jovian system, and time-lapse movies made from its images of Jupiter showed how the planet had changed since Voyager 1's visit. Its images of Io revealed changes in the moon's surface and the persistence of its volcanic eruptions. The spacecraft resolved the streaks Voyager 1 had shown on Europa into a collection of cracks in a thick and remarkably smooth icy crust. It also discovered a 14th moon and revealed a third component to the planet's rings.", - Image = "https://www.nasa.gov/sites/default/files/styles/full_width/public/thumbnails/image/voyager_2_jupiter_full_planet_incl_great_red_spot.jpg?itok=lSyZCyab" + Image = "https://data.openspaceproject.com/missions/voyager/voyager_2_jupiter_full_planet_incl_great_red_spot.png" }, { Name = "Voyager 1 Saturn Encounter", Date = "1980 NOV 09 00:00:00", - Image = "https://voyager.jpl.nasa.gov/assets/images/galleries/images-voyager-took/saturn/1bg.jpg" + Image = "https://data.openspaceproject.com/missions/voyager/1bg.jpg" }, { Name = "Voyager 2 Saturn Encounter", Date = "1981 AUG 25 00:00:00", Description = "Voyager 2 was to become the third spacecraft to visit Saturn. It gave us another close-range look at Saturn and its moons. Using its photopolarimeter, an instrument that had failed on Voyager 1, Voyager 2 was able to observe the planet's rings at much higher resolution and to discover many more ringlets. It also provided more detailed images of the ring spokes and kinks, and of the F-ring and its shepherding moons. Finally, it employed a gravity-assist maneuver at Saturn to help it reach its next destination, Uranus.", - Image = "https://voyager.jpl.nasa.gov/assets/images/galleries/images-voyager-took/saturn/saturn.gif" + Image = "https://data.openspaceproject.com/missions/voyager/saturn.gif" }, { Name = "Voyager 2 Uranus Encounter", Date = "1986 JAN 24 00:00:00", - Image = "https://solarsystem.nasa.gov/internal_resources/445/", + Image = "https://data.openspaceproject.com/missions/voyager/PIA00346_modest.jpg", Description = "Following its flybys of Jupiter and Saturn, Voyager 2 became the first spacecraft to visit Uranus. Voyager 2 remains the only spacecraft to have flown by Uranus. The planet appeared to have few features but Voyager 2 found evidence of an ocean of boiling water about 500 miles (800 kilometers) below its cloud tops. Curiously, the average temperature of its Sun-facing pole was found to be the same as that at the equator. Voyager 2 discovered 10 new moons, two new rings, and a strangely tilted magnetic field stronger than that of Saturn. A gravity assist at Uranus propelled the spacecraft toward its next destination, Neptune." }, { Name = "Voyager 2 Neptune Encounter", Date = "1989 AUG 25 00:00:00", - Image = "https://solarsystem.nasa.gov/internal_resources/444/", + Image = "https://data.openspaceproject.com/missions/voyager/PIA01492_modest.jpg", Description = "Voyager 2 is the only human-made object to have flown by Neptune. In the closest approach of its entire tour, the spacecraft passed less than 3,100 miles (5,000 kilometers) above the planet's cloud tops. It discovered five moons, four rings, and a 'Great Dark Spot' that vanished by the time the Hubble Space Telescope imaged Neptune five years later. Neptune's largest moon, Triton, was found to be the coldest known planetary body in the solar system, with a nitrogen ice 'volcano' on its surface." }, { @@ -69,12 +69,12 @@ local Mission = { Name = "Launches", TimeRange = { Start = "1977 AUG 20 00:00:00", End = "1977 SEP 05 00:00:00" }, Description = "Both the Voyager spacecrafts carries a gold plated record that contains information about their home planet, including recordings of terrestrial sounds, music and greetings in 55 languages. Instructions on how to play the record are also included.", - Image = "https://www.nasa.gov/sites/default/files/styles/full_width/public/thumbnails/image/voyager_golden_record_0.jpg?itok=ujFbQDyF", + Image = "https://data.openspaceproject.com/missions/voyager/voyager_golden_record_0.jpg", Phases = { { Name = "Voyager 2 Launch", TimeRange = { Start = "1977 AUG 20 00:00:00", End = "1977 AUG 20 00:00:00" }, - Image = "https://solarsystem.nasa.gov/internal_resources/446/" + Image = "https://data.openspaceproject.com/missions/voyager/image_1_pia01480.jpg" }, { Name = "Voyager 1 Launch", diff --git a/data/assets/scene/solarsystem/missions/voyager/voyager1.asset b/data/assets/scene/solarsystem/missions/voyager/voyager1.asset index c328d4a974..f101d17ec2 100644 --- a/data/assets/scene/solarsystem/missions/voyager/voyager1.asset +++ b/data/assets/scene/solarsystem/missions/voyager/voyager1.asset @@ -99,7 +99,8 @@ local VoyagerTrailCruiseEarthJupiter = { Tag = { "voyager1_trail" }, GUI = { Name = "Voyager 1 Trail Cruise Earth-Jupiter", - Path = "/Solar System/Missions/Voyager 1" + Path = "/Solar System/Missions/Voyager 1", + Focusable = false } } @@ -124,7 +125,8 @@ local VoyagerTrailEncounterJupiter = { Tag = { "voyager1_trail" }, GUI = { Name = "Voyager 1 Trail Encounter Jupiter", - Path = "/Solar System/Missions/Voyager 1" + Path = "/Solar System/Missions/Voyager 1", + Focusable = false } } @@ -147,7 +149,8 @@ local VoyagerTrailCruiseJupiterSaturn = { Tag = { "voyager1_trail" }, GUI = { Name = "Voyager 1 Trail Cruise Jupiter-Saturn", - Path = "/Solar System/Missions/Voyager 1" + Path = "/Solar System/Missions/Voyager 1", + Focusable = false } } @@ -172,7 +175,8 @@ local VoyagerTrailEncounterSaturn = { Tag = { "voyager1_trail" }, GUI = { Name = "Voyager 1 Trail Encounter Saturn", - Path = "/Solar System/Missions/Voyager 1" + Path = "/Solar System/Missions/Voyager 1", + Focusable = false } } @@ -195,7 +199,8 @@ local VoyagerTrailCruiseSaturnInf = { Tag = { "voyager1_trail" }, GUI = { Name = "Voyager 1 Trail Cruise Saturn-Inf", - Path = "/Solar System/Missions/Voyager 1" + Path = "/Solar System/Missions/Voyager 1", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/voyager/voyager2.asset b/data/assets/scene/solarsystem/missions/voyager/voyager2.asset index 178428d12c..a855ff0a0e 100644 --- a/data/assets/scene/solarsystem/missions/voyager/voyager2.asset +++ b/data/assets/scene/solarsystem/missions/voyager/voyager2.asset @@ -102,7 +102,8 @@ local VoyagerTrailCruiseEarthJupiter = { Tag = { "voyager2_trail" }, GUI = { Name = "Voyager 2 Trail Cruise Earth-Jupiter", - Path = "/Solar System/Missions/Voyager 2" + Path = "/Solar System/Missions/Voyager 2", + Focusable = false } } @@ -127,7 +128,8 @@ local VoyagerTrailEncounterJupiter = { Tag = { "voyager2_trail" }, GUI = { Name = "Voyager 2 Trail Encounter Jupiter", - Path = "/Solar System/Missions/Voyager 2" + Path = "/Solar System/Missions/Voyager 2", + Focusable = false } } @@ -150,7 +152,8 @@ local VoyagerTrailCruiseJupiterSaturn = { Tag = { "voyager2_trail" }, GUI = { Name = "Voyager 2 Trail Cruise Jupiter-Saturn", - Path = "/Solar System/Missions/Voyager 2" + Path = "/Solar System/Missions/Voyager 2", + Focusable = false } } @@ -175,7 +178,8 @@ local VoyagerTrailEncounterSaturn = { Tag = { "voyager2_trail" }, GUI = { Name = "Voyager 2 Trail Encounter Saturn", - Path = "/Solar System/Missions/Voyager 2" + Path = "/Solar System/Missions/Voyager 2", + Focusable = false } } @@ -198,7 +202,8 @@ local VoyagerTrailCruiseSaturnUranus = { Tag = { "voyager2_trail" }, GUI = { Name = "Voyager 2 Trail Cruise Saturn-Uranus", - Path = "/Solar System/Missions/Voyager 2" + Path = "/Solar System/Missions/Voyager 2", + Focusable = false } } @@ -223,7 +228,8 @@ local VoyagerTrailEncounterUranus = { Tag = { "voyager2_trail" }, GUI = { Name = "Voyager 2 Trail Encounter Uranus", - Path = "/Solar System/Missions/Voyager 2" + Path = "/Solar System/Missions/Voyager 2", + Focusable = false } } @@ -246,7 +252,8 @@ local VoyagerTrailCruiseUranusNeptune = { Tag = { "voyager2_trail" }, GUI = { Name = "Voyager 2 Trail Cruise Uranus-Neptune", - Path = "/Solar System/Missions/Voyager 2" + Path = "/Solar System/Missions/Voyager 2", + Focusable = false } } @@ -271,7 +278,8 @@ local VoyagerTrailEncounterNeptune = { Tag = { "voyager2_trail" }, GUI = { Name = "Voyager 2 Trail Encounter Neptune", - Path = "/Solar System/Missions/Voyager 2" + Path = "/Solar System/Missions/Voyager 2", + Focusable = false } } @@ -294,7 +302,8 @@ local VoyagerTrailCruiseNeptuneInf = { Tag = { "voyager2_trail" }, GUI = { Name = "Voyager 2 Trail Cruise Neptune-Inf", - Path = "/Solar System/Missions/Voyager 2" + Path = "/Solar System/Missions/Voyager 2", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/missions/voyagerpioneer/voyager1_2__pioneer10_11.asset b/data/assets/scene/solarsystem/missions/voyagerpioneer/voyager1_2__pioneer10_11.asset deleted file mode 100644 index 523c0892b3..0000000000 --- a/data/assets/scene/solarsystem/missions/voyagerpioneer/voyager1_2__pioneer10_11.asset +++ /dev/null @@ -1,164 +0,0 @@ -local ssb = asset.require("scene/solarsystem/sun/transforms") - -local voyager_horizons = asset.resource({ - Name = "Voyager horizons", - Type = "HttpSynchronization", - Identifier = "voyager_horizons", - Version = 1 -}) - -local pioneer_horizons = asset.resource({ - Name = "Pioneer horizons", - Type = "HttpSynchronization", - Identifier = "pioneer_horizons", - Version = 1 -}) - - -local Voyager1 = { - Identifier = "Voyager1", - Parent = ssb.SolarSystemBarycenter.Identifier, - Renderable = { - Type = "RenderableTrailTrajectory", - Enabled = false, - Translation = { - Type = "HorizonsTranslation", - HorizonsTextFile = voyager_horizons .. "voyager_1.hrz" - -- Target: Voyager 1 (spacecraft) (-31) - -- Observer: SSB - -- Start time: 1977-Sep-06 00:00:00 (first data point) - -- End time: 2030-Jan-01 00:00:00 (last data point) - -- Step size: 1 day - }, - Color = { 0.9, 0.9, 0.0 }, - Fade = 5.0, - StartTime = "1977 SEP 06 00:00:00", - EndTime = "2030 JAN 01 00:00:00", - SampleInterval = openspace.time.secondsPerDay() - }, - GUI = { - Name = "Voyager 1 Trail", - Path = "/Solar System/Missions/Voyager", - Description = [[Voyager 1 Trail, spanning September 6th, 1977 to January 1st, 2030. - Data from JPL Horizons]] - } -} - -local Voyager2 = { - Identifier = "Voyager2", - Parent = ssb.SolarSystemBarycenter.Identifier, - Renderable = { - Type = "RenderableTrailTrajectory", - Enabled = false, - Translation = { - Type = "HorizonsTranslation", - HorizonsTextFile = voyager_horizons .. "voyager_2.hrz" - -- Target: Voyager 2 (spacecraft) (-32) - -- Observer: SSB - -- Start time: 1977-Aug-21 00:00:00 (first data point) - -- End time: 2030-Jan-01 00:00:00 (last data point) - -- Step size: 1 day - }, - Color = { 0.9, 0.9, 0.0 }, - Fade = 5.0, - StartTime = "1977 AUG 21 00:00:00", - EndTime = "2030 JAN 01 00:00:00", - SampleInterval = openspace.time.secondsPerDay() - }, - GUI = { - Name = "Voyager 2 Trail", - Path = "/Solar System/Missions/Voyager", - Description = [[Voyager 2 Trail, spanning August 21st, 1977 to January 1st, 2030. - Data from JPL Horizons]] - } -} - -local Pioneer10 = { - Identifier = "Pioneer10", - Parent = ssb.SolarSystemBarycenter.Identifier, - Renderable = { - Type = "RenderableTrailTrajectory", - Enabled = false, - Translation = { - Type = "HorizonsTranslation", - HorizonsTextFile = pioneer_horizons .. "pioneer_10.hrz" - -- Target: Pioneer 10 (spacecraft) (-23) - -- Observer: SSB - -- Start time: 1972-Mar-04 00:00:00 (first data point) - -- End time: 2030-Jan-01 00:00:00 (last data point) - -- Step size: 1 day - }, - Color = { 0.9, 0.3, 0.0 }, - Fade = 5.0, - StartTime = "1972 MAR 04 00:00:00", - EndTime = "2030 JAN 01 00:00:00", - SampleInterval = openspace.time.secondsPerDay() - }, - GUI = { - Name = "Pioneer 10 Trail", - Path = "/Solar System/Missions/Pioneer", - Description = [[Pioneer 10 Trail, spanning March 4th, 1972 to January 1st, 2030. - Data from JPL Horizons]] - } -} - -local Pioneer11 ={ - Identifier = "Pioneer11", - Parent = ssb.SolarSystemBarycenter.Identifier, - Renderable = { - Type = "RenderableTrailTrajectory", - Enabled = false, - Translation = { - Type = "HorizonsTranslation", - HorizonsTextFile = pioneer_horizons .. "pioneer_11.hrz" - -- Target: Pioneer 11 (spacecraft) (-24) - -- Observer: SSB - -- Start time: 1973-Apr-07 00:00:00 (first data point) - -- End time: 2030-Jan-01 00:00:00 (last data point) - -- Step size: 1 day - }, - Color = { 0.9, 0.3, 0.0 }, - Fade = 5.0, - StartTime = "1973 APR 07 00:00:00", - EndTime = "2030 JAN 01 00:00:00", - SampleInterval = openspace.time.secondsPerDay() - }, - GUI = { - Name = "Pioneer 11 Trail", - Path = "/Solar System/Missions/Pioneer", - Description = [[Pioneer 11 Trail, spanning April 7th, 1973 to January 1st, 2030. - Data from JPL Horizons]] - } -} - - -asset.onInitialize(function() - openspace.addSceneGraphNode(Voyager1) - openspace.addSceneGraphNode(Voyager2) - openspace.addSceneGraphNode(Pioneer10) - openspace.addSceneGraphNode(Pioneer11) -end) - -asset.onDeinitialize(function() - openspace.removeSceneGraphNode(Pioneer11) - openspace.removeSceneGraphNode(Pioneer10) - openspace.removeSceneGraphNode(Voyager2) - openspace.removeSceneGraphNode(Voyager1) -end) - -asset.export(Voyager1) -asset.export(Voyager2) -asset.export(Pioneer10) -asset.export(Pioneer11) - - - -asset.meta = { - Name = "Pioneer and Voyager Trails", - Description = [[Pioneer 10, Pioneer 11, Voyager 1 and Voyager 2 trails. Driven by JPL - Horizons data for better performance then spice but lower resolution. Data is from - shortly after mission launches until January 1st, 2030]], - Author = "OpenSpace Team", - URL = "http://openspaceproject.com", - License = "MIT license" -} diff --git a/data/assets/scene/solarsystem/planets/earth/atmosphere.asset b/data/assets/scene/solarsystem/planets/earth/atmosphere.asset index b112638123..377abbe9e7 100644 --- a/data/assets/scene/solarsystem/planets/earth/atmosphere.asset +++ b/data/assets/scene/solarsystem/planets/earth/atmosphere.asset @@ -82,7 +82,8 @@ local Atmosphere = { GUI = { Name = "Earth Atmosphere", Path = "/Solar System/Planets/Earth", - Description = "Atmosphere of Earth" + Description = "Atmosphere of Earth", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/earth.asset b/data/assets/scene/solarsystem/planets/earth/earth.asset index e8917f7928..781200580c 100644 --- a/data/assets/scene/solarsystem/planets/earth/earth.asset +++ b/data/assets/scene/solarsystem/planets/earth/earth.asset @@ -70,7 +70,8 @@ local EarthLabel = { GUI = { Name = "Earth Label", Path = "/Solar System/Planets/Earth", - Description = "Main label for Earth" + Description = "Main label for Earth", + Focusable = false } } @@ -90,13 +91,32 @@ local FocusEarth = { local ToggleSatelliteTrails = { Identifier = "os.solarsystem.ToggleSatelliteTrails", Name = "Toggle satellite trails", - Command = [[ - local list = openspace.property("{earth_satellites}.Renderable.Enabled") - for _,v in pairs(list) do - openspace.setPropertyValueSingle(v, not openspace.propertyValue(v)) - end + Command = [[openspace.toggleFade("{earth_satellites~space_stations}.Renderable")]], + Documentation = [[ + Toggle trails on or off for the satellites around Earth (excluding space stations) + ]], + GuiPath = "/Solar System/Earth", + IsLocal = false +} + +local ToggleSpaceStations = { + Identifier = "os.solarsystem.ToggleSpaceStations", + Name = "Toggle space stations", + Command = [[openspace.toggleFade("{space_stations}.Renderable")]], + Documentation = [[ + Toggle visiblity of the space stations around Earth (including their trail). + ]], + GuiPath = "/Solar System/Earth", + IsLocal = false +} + +local ToggleSpaceStationTrails = { + Identifier = "os.solarsystem.ToggleSpaceStationTrails", + Name = "Toggle space station trails", + Command = [[openspace.toggleFade("{space_stations&trails}.Renderable")]], + Documentation = [[ + Toggle visiblity of the trails for the space stations around Earth. ]], - Documentation = "Toggle trails on or off for satellites around Earth", GuiPath = "/Solar System/Earth", IsLocal = false } @@ -108,9 +128,13 @@ asset.onInitialize(function() openspace.action.registerAction(FocusEarth) openspace.action.registerAction(ToggleSatelliteTrails) + openspace.action.registerAction(ToggleSpaceStations) + openspace.action.registerAction(ToggleSpaceStationTrails) end) asset.onDeinitialize(function() + openspace.action.removeAction(ToggleSpaceStationTrails) + openspace.action.removeAction(ToggleSpaceStations) openspace.action.removeAction(ToggleSatelliteTrails) openspace.action.removeAction(FocusEarth) diff --git a/data/assets/scene/solarsystem/planets/earth/eclipse_shadow.asset b/data/assets/scene/solarsystem/planets/earth/eclipse_shadow.asset index 6543fcc589..9d5cf3a6a4 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipse_shadow.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipse_shadow.asset @@ -20,7 +20,8 @@ local EarthMoonShadow = { }, GUI = { Name = "Earth/Moon Shadow", - Path = "/Solar System/Planets/Earth" + Path = "/Solar System/Planets/Earth", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2003-05-31.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2003-05-31.asset index cd2120ace3..a9a3aa1bd7 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2003-05-31.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2003-05-31.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Annular 2003-05-31", - Description = "Annular eclipse map for 2003-05-31", + Description = [[Annular eclipse map for 2003-05-31. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2005-10-03.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2005-10-03.asset index 8c067aebfe..85c441d79f 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2005-10-03.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2005-10-03.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Annular 2005-10-03", - Description = "Annular eclipse map for 2005-10-03", + Description = [[Annular eclipse map for 2005-10-03. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2006-09-22.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2006-09-22.asset index fd880a3381..ca6ac6d311 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2006-09-22.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2006-09-22.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Annular 2006-09-22", - Description = "Annular eclipse map for 2006-09-22", + Description = [[Annular eclipse map for 2006-09-22. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2008-02-07.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2008-02-07.asset index 07a87ff0e3..0968aa0896 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2008-02-07.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2008-02-07.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Annular 2008-02-07", - Description = "Annular eclipse map for 2008-02-07", + Description = [[Annular eclipse map for 2008-02-07. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2009-01-26.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2009-01-26.asset index 8d5b5ba5b4..6249e71ac3 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2009-01-26.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2009-01-26.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Annular 2009-01-26", - Description = "Annular eclipse map for 2009-01-26", + Description = [[Annular eclipse map for 2009-01-26. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2010-01-15.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2010-01-15.asset index 85b778302c..ba1307a69f 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2010-01-15.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2010-01-15.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Annular 2010-01-15", - Description = "Annular eclipse map for 2010-01-15", + Description = [[Annular eclipse map for 2010-01-15. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2012-05-20.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2012-05-20.asset index 6a6cbac1bc..f91590ca05 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2012-05-20.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2012-05-20.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Annular 2012-05-20", - Description = "Annular eclipse map for 2012-05-20", + Description = [[Annular eclipse map for 2012-05-20. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2013-05-10.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2013-05-10.asset index 3afe637ea7..e298936ba6 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2013-05-10.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2013-05-10.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Annular 2013-05-10", - Description = "Annular eclipse map for 2013-05-10", + Description = [[Annular eclipse map for 2013-05-10. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2014-04-29.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2014-04-29.asset index 893e63c166..a62f7439be 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2014-04-29.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2014-04-29.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Annular 2014-04-29", - Description = "Annular eclipse map for 2014-04-29", + Description = [[Annular eclipse map for 2014-04-29. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2016-09-01.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2016-09-01.asset index 6595181954..45e993edcb 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2016-09-01.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2016-09-01.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Annular 2016-09-01", - Description = "Annular eclipse map for 2016-09-01", + Description = [[Annular eclipse map for 2016-09-01. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2017-02-26.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2017-02-26.asset index b0ddff5030..6a193c15cc 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2017-02-26.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2017-02-26.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Annular 2017-02-26", - Description = "Annular eclipse map for 2017-02-26", + Description = [[Annular eclipse map for 2017-02-26. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2019-12-26.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2019-12-26.asset index cdfdcbbc73..a37008c264 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2019-12-26.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2019-12-26.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Annular 2019-12-26", - Description = "Annular eclipse map for 2019-12-26", + Description = [[Annular eclipse map for 2019-12-26. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2020-06-21.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2020-06-21.asset index 31c3f77c4f..db57e1e00b 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2020-06-21.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2020-06-21.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Annular 2020-06-21", - Description = "Annular eclipse map for 2020-06-21", + Description = [[Annular eclipse map for 2020-06-21. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2021-06-10.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2021-06-10.asset index d680c04d89..c436a6fc72 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2021-06-10.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2021-06-10.asset @@ -28,7 +28,8 @@ end) asset.meta = { Name = "Annular 2021-06-10", - Description = "Annular eclipse map for 2021-06-10", + Description = [[Annular eclipse map for 2021-06-10. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2023-10-14.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2023-10-14.asset index 6fa8c35393..de33ca863d 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2023-10-14.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2023-10-14.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Annular 2023-10-14", - Description = "Annular eclipse map for 2023-10-14", + Description = [[Annular eclipse map for 2023-10-14. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2024-10-02.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2024-10-02.asset index be7c775d48..acce2c21a7 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2024-10-02.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2024-10-02.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Annular 2024-10-02", - Description = "Annular eclipse map for 2024-10-02", + Description = [[Annular eclipse map for 2024-10-02. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2026-02-17.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2026-02-17.asset index ac4a8e7152..bed76fb0ca 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2026-02-17.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2026-02-17.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Annular 2026-02-17", - Description = "Annular eclipse map for 2026-02-17", + Description = [[Annular eclipse map for 2026-02-17. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2027-02-06.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2027-02-06.asset index 3df7a73fa4..28b254aac5 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2027-02-06.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2027-02-06.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Annular 2027-02-06", - Description = "Annular eclipse map for 2027-02-06", + Description = [[Annular eclipse map for 2027-02-06. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2028-01-26.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2028-01-26.asset index 74069fc105..dbee44b722 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2028-01-26.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2028-01-26.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Annular 2028-01-26", - Description = "Annular eclipse map for 2028-01-26", + Description = [[Annular eclipse map for 2028-01-26. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2030-06-01.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2030-06-01.asset index 77e6fc68a6..a9c8106a27 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2030-06-01.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/annular/2030-06-01.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Annular 2030-06-01", - Description = "Annular eclipse map for 2030-06-01", + Description = [[Annular eclipse map for 2030-06-01. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/hybrid/2005-04-08.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/hybrid/2005-04-08.asset index 2c8dcc13b8..3719573088 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/hybrid/2005-04-08.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/hybrid/2005-04-08.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Hybrid 2005-04-08", - Description = "Hybrid eclipse map for 2005-04-08", + Description = [[Hybrid eclipse map for 2005-04-08. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/hybrid/2013-11-03.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/hybrid/2013-11-03.asset index 324a4873a7..ed9de86b3c 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/hybrid/2013-11-03.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/hybrid/2013-11-03.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Hybrid 2013-11-03", - Description = "Hybrid eclipse map for 2013-11-03", + Description = [[Hybrid eclipse map for 2013-11-03. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/hybrid/2023-04-20.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/hybrid/2023-04-20.asset index a73f860353..bdede016a4 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/hybrid/2023-04-20.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/hybrid/2023-04-20.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Hybrid 2023-04-20", - Description = "Hybrid eclipse map for 2023-04-20", + Description = [[Hybrid eclipse map for 2023-04-20. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/hybrid/2031-11-14.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/hybrid/2031-11-14.asset index 833ae519a2..a646f6478e 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/hybrid/2031-11-14.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/hybrid/2031-11-14.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Hybrid 2031-11-14", - Description = "Hybrid eclipse map for 2031-11-14", + Description = [[Hybrid eclipse map for 2031-11-14. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2003-11-23.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2003-11-23.asset index e37b14ffd0..77a419f5bf 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2003-11-23.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2003-11-23.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Total 2003-11-23", - Description = "Total eclipse map for 2003-11-23", + Description = [[Total eclipse map for 2003-11-23. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2006-03-29.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2006-03-29.asset index 2e90cf30a0..f92bb211e4 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2006-03-29.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2006-03-29.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Total 2006-03-29", - Description = "Total eclipse map for 2006-03-29", + Description = [[Total eclipse map for 2006-03-29. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2008-08-01.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2008-08-01.asset index 5954ae4231..5501b12473 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2008-08-01.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2008-08-01.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Total 2008-08-01", - Description = "Total eclipse map for 2008-08-01", + Description = [[Total eclipse map for 2008-08-01. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2009-07-22.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2009-07-22.asset index 08c268e486..00adeafaa0 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2009-07-22.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2009-07-22.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Total 2009-07-22", - Description = "Total eclipse map for 2009-07-22", + Description = [[Total eclipse map for 2009-07-22. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2010-07-11.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2010-07-11.asset index 203feea490..1f8db0c516 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2010-07-11.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2010-07-11.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Total 2010-07-11", - Description = "Total eclipse map for 2010-07-11", + Description = [[Total eclipse map for 2010-07-11. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2012-11-13.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2012-11-13.asset index 9afec60525..191b3df770 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2012-11-13.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2012-11-13.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Total 2012-11-13", - Description = "Total eclipse map for 2012-11-13", + Description = [[Total eclipse map for 2012-11-13. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2015-03-20.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2015-03-20.asset index e733aa5b3a..5f1ed564fd 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2015-03-20.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2015-03-20.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Total 2015-03-20", - Description = "Total eclipse map for 2015-03-20", + Description = [[Total eclipse map for 2015-03-20. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2016-03-09.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2016-03-09.asset index aad772655f..436354b7bd 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2016-03-09.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2016-03-09.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Total 2016-03-09", - Description = "Total eclipse map for 2016-03-09", + Description = [[Total eclipse map for 2016-03-09. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2017-08-21.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2017-08-21.asset index 4d8b25b734..41a3bbecd3 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2017-08-21.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2017-08-21.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Total 2017-08-21", - Description = "Total eclipse map for 2017-08-21", + Description = [[Total eclipse map for 2017-08-21. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2019-07-02.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2019-07-02.asset index 463955f014..493d81c507 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2019-07-02.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2019-07-02.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Total 2019-07-02", - Description = "Total eclipse map for 2019-07-02", + Description = [[Total eclipse map for 2019-07-02. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2020-12-14.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2020-12-14.asset index d14ce27524..6520c53e99 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2020-12-14.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2020-12-14.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Total 2020-12-14", - Description = "Total eclipse map for 2020-12-14", + Description = [[Total eclipse map for 2020-12-14. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2021-12-04.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2021-12-04.asset index 341a466735..a20e63bb4d 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2021-12-04.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2021-12-04.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Total 2021-12-04", - Description = "Total eclipse map for 2021-12-04", + Description = [[Total eclipse map for 2021-12-04. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2024-04-08.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2024-04-08.asset index 4d1bf0a6a2..408370c228 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2024-04-08.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2024-04-08.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Total 2024-04-08", - Description = "Total eclipse map for 2024-04-08", + Description = [[Total eclipse map for 2024-04-08. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2026-08-12.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2026-08-12.asset index dd3cc09e19..3ba33d7bf4 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2026-08-12.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2026-08-12.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Total 2026-08-12", - Description = "Total eclipse map for 2026-08-12", + Description = [[Total eclipse map for 2026-08-12. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2027-08-02.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2027-08-02.asset index f5c7bb3ac0..92fce0a315 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2027-08-02.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2027-08-02.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Total 2027-08-02", - Description = "Total eclipse map for 2027-08-02", + Description = [[Total eclipse map for 2027-08-02. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2028-07-22.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2028-07-22.asset index d27392a283..d1008605e6 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2028-07-22.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2028-07-22.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Total 2028-07-22", - Description = "Total eclipse map for 2028-07-22", + Description = [[Total eclipse map for 2028-07-22. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2030-11-25.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2030-11-25.asset index 7b269d180f..a0f68e439d 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2030-11-25.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2030-11-25.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Total 2030-11-25", - Description = "Total eclipse map for 2030-11-25", + Description = [[Total eclipse map for 2030-11-25. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2033-03-30.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2033-03-30.asset index 503855985d..955cf4886d 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2033-03-30.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2033-03-30.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Total 2033-03-30", - Description = "Total eclipse map for 2033-03-30", + Description = [[Total eclipse map for 2033-03-30. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2034-03-20.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2034-03-20.asset index a1168bfe2b..c29f3451d8 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2034-03-20.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2034-03-20.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Total 2034-03-20", - Description = "Total eclipse map for 2034-03-20", + Description = [[Total eclipse map for 2034-03-20. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2035-09-02.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2035-09-02.asset index cf7827acc5..211ccc9896 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2035-09-02.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2035-09-02.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Total 2035-09-02", - Description = "Total eclipse map for 2035-09-02", + Description = [[Total eclipse map for 2035-09-02. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2037-07-13.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2037-07-13.asset index 15fc082dab..0c8b324a7a 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2037-07-13.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2037-07-13.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Total 2037-07-13", - Description = "Total eclipse map for 2037-07-13", + Description = [[Total eclipse map for 2037-07-13. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2038-12-26.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2038-12-26.asset index 92c3bf1de0..331bde6dac 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2038-12-26.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2038-12-26.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Total 2038-12-26", - Description = "Total eclipse map for 2038-12-26", + Description = [[Total eclipse map for 2038-12-26. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2039-12-15.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2039-12-15.asset index 53edd247ef..1f13213562 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2039-12-15.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2039-12-15.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Total 2039-12-15", - Description = "Total eclipse map for 2039-12-15", + Description = [[Total eclipse map for 2039-12-15. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2041-04-30.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2041-04-30.asset index 1d1a60b078..480e3fbe84 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2041-04-30.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2041-04-30.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Total 2041-04-30", - Description = "Total eclipse map for 2041-04-30", + Description = [[Total eclipse map for 2041-04-30. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2042-04-20.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2042-04-20.asset index f4fc2a76a1..56c4286a6d 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2042-04-20.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2042-04-20.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Total 2042-04-20", - Description = "Total eclipse map for 2042-04-20", + Description = [[Total eclipse map for 2042-04-20. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2043-04-09.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2043-04-09.asset index aa48d081eb..35414a57a8 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2043-04-09.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/paths/total/2043-04-09.asset @@ -27,7 +27,8 @@ end) asset.meta = { Name = "Total 2043-04-09", - Description = "Total eclipse map for 2043-04-09", + Description = [[Total eclipse map for 2043-04-09. The GeoJSON is adapted from the + data provided by Xavier M. Jubier (http://xjubier.free.fr).]], Author = "OpenSpace Team", URL = "http://openspaceproject.com", License = "MIT license" diff --git a/data/assets/scene/solarsystem/planets/earth/eclipses/timeline.asset b/data/assets/scene/solarsystem/planets/earth/eclipses/timeline.asset index a94559e606..ea7061782a 100644 --- a/data/assets/scene/solarsystem/planets/earth/eclipses/timeline.asset +++ b/data/assets/scene/solarsystem/planets/earth/eclipses/timeline.asset @@ -11,2262 +11,2262 @@ local Timeline = { { Name = "Total Eclipse", Date = "1901 May 18 05:33:48", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1901-05-18.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1901-05-18.gif" }, { Name = "Annular Eclipse", Date = "1901 Nov 11 07:28:21", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1901-11-11.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1901-11-11.gif" }, { Name = "Partial Eclipse", Date = "1902 Apr 08 14:05:06", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1902-04-08.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1902-04-08.gif" }, { Name = "Partial Eclipse", Date = "1902 May 07 22:34:16", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1902-05-07.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1902-05-07.gif" }, { Name = "Partial Eclipse", Date = "1902 Oct 31 08:00:18", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1902-10-31.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1902-10-31.gif" }, { Name = "Annular Eclipse", Date = "1903 Mar 29 01:35:2", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1903-03-29.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1903-03-29.gif" }, { Name = "Total Eclipse", Date = "1903 Sep 21 04:39:52", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1903-09-21.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1903-09-21.gif" }, { Name = "Annular Eclipse", Date = "1904 Mar 17 05:40:44", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1904-03-17.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1904-03-17.gif" }, { Name = "Total Eclipse", Date = "1904 Sep 09 20:44:21", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1904-09-09.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1904-09-09.gif" }, { Name = "Annular Eclipse", Date = "1905 Mar 06 05:12:26", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1905-03-06.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1905-03-06.gif" }, { Name = "Total Eclipse", Date = "1905 Aug 30 13:07:26", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1905-08-30.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1905-08-30.gif" }, { Name = "Partial Eclipse", Date = "1906 Feb 23 07:43:20", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1906-02-23.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1906-02-23.gif" }, { Name = "Partial Eclipse", Date = "1906 Jul 21 13:14:19", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1906-07-21.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1906-07-21.gif" }, { Name = "Partial Eclipse", Date = "1906 Aug 20 01:12:50", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1906-08-20.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1906-08-20.gif" }, { Name = "Total Eclipse", Date = "1907 Jan 14 06:05:43", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1907-01-14.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1907-01-14.gif" }, { Name = "Annular Eclipse", Date = "1907 Jul 10 15:24:32", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1907-07-10.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1907-07-10.gif" }, { Name = "Total Eclipse", Date = "1908 Jan 03 21:45:22", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1908-01-03.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1908-01-03.gif" }, { Name = "Annular Eclipse", Date = "1908 Jun 28 16:29:51", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1908-06-28.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1908-06-28.gif" }, { Name = "Hybrid Eclipse", Date = "1908 Dec 23 11:44:28", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1908-12-23.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1908-12-23.gif" }, { Name = "Hybrid Eclipse", Date = "1909 Jun 17 23:18:38", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1909-06-17.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1909-06-17.gif" }, { Name = "Partial Eclipse", Date = "1909 Dec 12 19:44:48", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1909-12-12.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1909-12-12.gif" }, { Name = "Total Eclipse", Date = "1910 May 09 05:42:13", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1910-05-09.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1910-05-09.gif" }, { Name = "Partial Eclipse", Date = "1910 Nov 02 02:08:32", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1910-11-02.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1910-11-02.gif" }, { Name = "Total Eclipse", Date = "1911 Apr 28 22:27:22", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1911-04-28.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1911-04-28.gif" }, { Name = "Annular Eclipse", Date = "1911 Oct 22 04:13:02", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1911-10-22.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1911-10-22.gif" }, { Name = "Hybrid Eclipse", Date = "1912 Apr 17 11:34:22", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1912-04-17.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1912-04-17.gif" }, { Name = "Total Eclipse", Date = "1912 Oct 10 13:36:14", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1912-10-10.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1912-10-10.gif" }, { Name = "Partial Eclipse", Date = "1913 Apr 06 17:33:07", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1913-04-06.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1913-04-06.gif" }, { Name = "Partial Eclipse", Date = "1913 Aug 31 20:52:12", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1913-08-31.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1913-08-31.gif" }, { Name = "Partial Eclipse", Date = "1913 Sep 30 04:45:49", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1913-09-30.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1913-09-30.gif" }, { Name = "Annular Eclipse", Date = "1914 Feb 25 00:13:01", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1914-02-25.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1914-02-25.gif" }, { Name = "Total Eclipse", Date = "1914 Aug 21 12:34:27", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1914-08-21.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1914-08-21.gif" }, { Name = "Annular Eclipse", Date = "1915 Feb 14 04:33:20", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1915-02-14.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1915-02-14.gif" }, { Name = "Annular Eclipse", Date = "1915 Aug 10 22:52:25", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1915-08-10.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1915-08-10.gif" }, { Name = "Total Eclipse", Date = "1916 Feb 03 16:00:21", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1916-02-03.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1916-02-03.gif" }, { Name = "Annular Eclipse", Date = "1916 Jul 30 02:06:10", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1916-07-30.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1916-07-30.gif" }, { Name = "Partial Eclipse", Date = "1916 Dec 24 20:46:22", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1916-12-24.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1916-12-24.gif" }, { Name = "Partial Eclipse", Date = "1917 Jan 23 07:28:31", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1917-01-23.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1917-01-23.gif" }, { Name = "Partial Eclipse", Date = "1917 Jun 19 13:16:21", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1917-06-19.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1917-06-19.gif" }, { Name = "Partial Eclipse", Date = "1917 Jul 19 02:42:42", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1917-07-19.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1917-07-19.gif" }, { Name = "Annular Eclipse", Date = "1917 Dec 14 09:27:20", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1917-12-14.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1917-12-14.gif" }, { Name = "Total Eclipse", Date = "1918 Jun 08 22:07:43", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1918-06-08.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1918-06-08.gif" }, { Name = "Annular Eclipse", Date = "1918 Dec 03 15:22:02", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1918-12-03.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1918-12-03.gif" }, { Name = "Total Eclipse", Date = "1919 May 29 13:08:55", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1919-05-29.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1919-05-29.gif" }, { Name = "Annular Eclipse", Date = "1919 Nov 22 15:14:12", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1919-11-22.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1919-11-22.gif" }, { Name = "Partial Eclipse", Date = "1920 May 18 06:14:55", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1920-05-18.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1920-05-18.gif" }, { Name = "Partial Eclipse", Date = "1920 Nov 10 15:52:15", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1920-11-10.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1920-11-10.gif" }, { Name = "Annular Eclipse", Date = "1921 Apr 08 09:15:01", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1921-04-08.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1921-04-08.gif" }, { Name = "Total Eclipse", Date = "1921 Oct 01 12:35:58", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1921-10-01.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1921-10-01.gif" }, { Name = "Annular Eclipse", Date = "1922 Mar 28 13:05:26", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1922-03-28.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1922-03-28.gif" }, { Name = "Total Eclipse", Date = "1922 Sep 21 04:40:31", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1922-09-21.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1922-09-21.gif" }, { Name = "Annular Eclipse", Date = "1923 Mar 17 12:44:58", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1923-03-17.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1923-03-17.gif" }, { Name = "Total Eclipse", Date = "1923 Sep 10 20:47:29", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1923-09-10.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1923-09-10.gif" }, { Name = "Partial Eclipse", Date = "1924 Mar 05 15:44:20", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1924-03-05.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1924-03-05.gif" }, { Name = "Partial Eclipse", Date = "1924 Jul 31 19:58:20", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1924-07-31.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1924-07-31.gif" }, { Name = "Partial Eclipse", Date = "1924 Aug 30 08:23:00", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1924-08-30.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1924-08-30.gif" }, { Name = "Total Eclipse", Date = "1925 Jan 24 14:54:03", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1925-01-24.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1925-01-24.gif" }, { Name = "Annular Eclipse", Date = "1925 Jul 20 21:48:42", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1925-07-20.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1925-07-20.gif" }, { Name = "Total Eclipse", Date = "1926 Jan 14 06:36:58", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1926-01-14.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1926-01-14.gif" }, { Name = "Annular Eclipse", Date = "1926 Jul 09 23:06:02", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1926-07-09.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1926-07-09.gif" }, { Name = "Annular Eclipse", Date = "1927 Jan 03 20:22:53", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1927-01-03.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1927-01-03.gif" }, { Name = "Total Eclipse", Date = "1927 Jun 29 06:23:27", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1927-06-29.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1927-06-29.gif" }, { Name = "Partial Eclipse", Date = "1927 Dec 24 03:59:41", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1927-12-24.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1927-12-24.gif" }, { Name = "Total Eclipse", Date = "1928 May 19 13:24:20", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1928-05-19.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1928-05-19.gif" }, { Name = "Partial Eclipse", Date = "1928 Jun 17 20:27:28", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1928-06-17.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1928-06-17.gif" }, { Name = "Partial Eclipse", Date = "1928 Nov 12 09:48:24", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1928-11-12.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1928-11-12.gif" }, { Name = "Total Eclipse", Date = "1929 May 09 06:10:34", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1929-05-09.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1929-05-09.gif" }, { Name = "Annular Eclipse", Date = "1929 Nov 01 12:05:10", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1929-11-01.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1929-11-01.gif" }, { Name = "Hybrid Eclipse", Date = "1930 Apr 28 19:03:34", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1930-04-28.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1930-04-28.gif" }, { Name = "Total Eclipse", Date = "1930 Oct 21 21:43:53", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1930-10-21.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1930-10-21.gif" }, { Name = "Partial Eclipse", Date = "1931 Apr 18 00:45:35", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1931-04-18.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1931-04-18.gif" }, { Name = "Partial Eclipse", Date = "1931 Sep 12 04:41:25", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1931-09-12.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1931-09-12.gif" }, { Name = "Partial Eclipse", Date = "1931 Oct 11 12:55:40", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1931-10-11.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1931-10-11.gif" }, { Name = "Annular Eclipse", Date = "1932 Mar 07 07:55:50", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1932-03-07.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1932-03-07.gif" }, { Name = "Total Eclipse", Date = "1932 Aug 31 20:03:41", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1932-08-31.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1932-08-31.gif" }, { Name = "Annular Eclipse", Date = "1933 Feb 24 12:46:39", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1933-02-24.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1933-02-24.gif" }, { Name = "Annular Eclipse", Date = "1933 Aug 21 05:49:11", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1933-08-21.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1933-08-21.gif" }, { Name = "Total Eclipse", Date = "1934 Feb 14 00:38:41", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1934-02-14.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1934-02-14.gif" }, { Name = "Annular Eclipse", Date = "1934 Aug 10 08:37:48", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1934-08-10.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1934-08-10.gif" }, { Name = "Partial Eclipse", Date = "1935 Jan 05 05:35:46", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1935-01-05.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1935-01-05.gif" }, { Name = "Partial Eclipse", Date = "1935 Feb 03 16:16:20", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1935-02-03.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1935-02-03.gif" }, { Name = "Partial Eclipse", Date = "1935 Jun 30 19:59:46", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1935-06-30.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1935-06-30.gif" }, { Name = "Partial Eclipse", Date = "1935 Jul 30 09:16:28", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1935-07-30.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1935-07-30.gif" }, { Name = "Annular Eclipse", Date = "1935 Dec 25 17:59:52", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1935-12-25.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1935-12-25.gif" }, { Name = "Total Eclipse", Date = "1936 Jun 19 05:20:31", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1936-06-19.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1936-06-19.gif" }, { Name = "Annular Eclipse", Date = "1936 Dec 13 23:28:12", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1936-12-13.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1936-12-13.gif" }, { Name = "Total Eclipse", Date = "1937 Jun 08 20:41:02", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1937-06-08.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1937-06-08.gif" }, { Name = "Annular Eclipse", Date = "1937 Dec 02 23:05:45", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1937-12-02.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1937-12-02.gif" }, { Name = "Total Eclipse", Date = "1938 May 29 13:50:19", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1938-05-29.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1938-05-29.gif" }, { Name = "Partial Eclipse", Date = "1938 Nov 21 23:52:25", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1938-11-21.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1938-11-21.gif" }, { Name = "Annular Eclipse", Date = "1939 Apr 19 16:45:53", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1939-04-19.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1939-04-19.gif" }, { Name = "Total Eclipse", Date = "1939 Oct 12 20:40:23", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1939-10-12.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1939-10-12.gif" }, { Name = "Annular Eclipse", Date = "1940 Apr 07 20:21:21", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1940-04-07.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1940-04-07.gif" }, { Name = "Total Eclipse", Date = "1940 Oct 01 12:44:06", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1940-10-01.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1940-10-01.gif" }, { Name = "Annular Eclipse", Date = "1941 Mar 27 20:08:08", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1941-03-27.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1941-03-27.gif" }, { Name = "Total Eclipse", Date = "1941 Sep 21 04:34:03", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1941-09-21.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1941-09-21.gif" }, { Name = "Partial Eclipse", Date = "1942 Mar 16 23:37:07", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1942-03-16.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1942-03-16.gif" }, { Name = "Partial Eclipse", Date = "1942 Aug 12 02:45:12", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1942-08-12.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1942-08-12.gif" }, { Name = "Partial Eclipse", Date = "1942 Sep 10 15:39:32", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1942-09-10.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1942-09-10.gif" }, { Name = "Total Eclipse", Date = "1943 Feb 04 23:38:10", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1943-02-04.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1943-02-04.gif" }, { Name = "Annular Eclipse", Date = "1943 Aug 01 04:16:13", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1943-08-01.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1943-08-01.gif" }, { Name = "Total Eclipse", Date = "1944 Jan 25 15:26:42", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1944-01-25.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1944-01-25.gif" }, { Name = "Annular Eclipse", Date = "1944 Jul 20 05:43:13", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1944-07-20.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1944-07-20.gif" }, { Name = "Annular Eclipse", Date = "1945 Jan 14 05:01:43", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1945-01-14.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1945-01-14.gif" }, { Name = "Total Eclipse", Date = "1945 Jul 09 13:27:45", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1945-07-09.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1945-07-09.gif" }, { Name = "Partial Eclipse", Date = "1946 Jan 03 12:16:11", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1946-01-03.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1946-01-03.gif" }, { Name = "Partial Eclipse", Date = "1946 May 30 21:00:24", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1946-05-30.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1946-05-30.gif" }, { Name = "Partial Eclipse", Date = "1946 Jun 29 03:51:58", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1946-06-29.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1946-06-29.gif" }, { Name = "Partial Eclipse", Date = "1946 Nov 23 17:37:12", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1946-11-23.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1946-11-23.gif" }, { Name = "Total Eclipse", Date = "1947 May 20 13:47:47", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1947-05-20.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1947-05-20.gif" }, { Name = "Annular Eclipse", Date = "1947 Nov 12 20:05:37", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1947-11-12.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1947-11-12.gif" }, { Name = "Annular Eclipse", Date = "1948 May 09 02:26:04", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1948-05-09.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1948-05-09.gif" }, { Name = "Total Eclipse", Date = "1948 Nov 01 05:59:18", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1948-11-01.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1948-11-01.gif" }, { Name = "Partial Eclipse", Date = "1949 Apr 28 07:48:53", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1949-04-28.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1949-04-28.gif" }, { Name = "Partial Eclipse", Date = "1949 Oct 21 21:13:01", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1949-10-21.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1949-10-21.gif" }, { Name = "Annular Eclipse", Date = "1950 Mar 18 15:32:01", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1950-03-18.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1950-03-18.gif" }, { Name = "Total Eclipse", Date = "1950 Sep 12 03:38:47", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1950-09-12.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1950-09-12.gif" }, { Name = "Annular Eclipse", Date = "1951 Mar 07 20:53:40", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1951-03-07.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1951-03-07.gif" }, { Name = "Annular Eclipse", Date = "1951 Sep 01 12:51:51", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1951-09-01.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1951-09-01.gif" }, { Name = "Total Eclipse", Date = "1952 Feb 25 09:11:35", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1952-02-25.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1952-02-25.gif" }, { Name = "Annular Eclipse", Date = "1952 Aug 20 15:13:35", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1952-08-20.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1952-08-20.gif" }, { Name = "Partial Eclipse", Date = "1953 Feb 14 00:59:30", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1953-02-14.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1953-02-14.gif" }, { Name = "Partial Eclipse", Date = "1953 Jul 11 02:44:14", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1953-07-11.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1953-07-11.gif" }, { Name = "Partial Eclipse", Date = "1953 Aug 09 15:55:03", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1953-08-09.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1953-08-09.gif" }, { Name = "Annular Eclipse", Date = "1954 Jan 05 02:32:01", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1954-01-05.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1954-01-05.gif" }, { Name = "Total Eclipse", Date = "1954 Jun 30 12:32:38", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1954-06-30.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1954-06-30.gif" }, { Name = "Annular Eclipse", Date = "1954 Dec 25 07:36:42", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1954-12-25.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1954-12-25.gif" }, { Name = "Total Eclipse", Date = "1955 Jun 20 04:10:42", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1955-06-20.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1955-06-20.gif" }, { Name = "Annular Eclipse", Date = "1955 Dec 14 07:02:25", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1955-12-14.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1955-12-14.gif" }, { Name = "Total Eclipse", Date = "1956 Jun 08 21:20:39", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1956-06-08.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1956-06-08.gif" }, { Name = "Partial Eclipse", Date = "1956 Dec 02 08:00:35", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1956-12-02.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1956-12-02.gif" }, { Name = "Annular Eclipse", Date = "1957 Apr 30 00:05:28", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1957-04-30.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1957-04-30.gif" }, { Name = "Total Eclipse", Date = "1957 Oct 23 04:54:02", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1957-10-23.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1957-10-23.gif" }, { Name = "Annular Eclipse", Date = "1958 Apr 19 03:27:17", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1958-04-19.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1958-04-19.gif" }, { Name = "Total Eclipse", Date = "1958 Oct 12 20:55:28", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1958-10-12.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1958-10-12.gif" }, { Name = "Annular Eclipse", Date = "1959 Apr 08 03:24:08", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1959-04-08.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1959-04-08.gif" }, { Name = "Total Eclipse", Date = "1959 Oct 02 12:27:00", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1959-10-02.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1959-10-02.gif" }, { Name = "Partial Eclipse", Date = "1960 Mar 27 07:25:07", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1960-03-27.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1960-03-27.gif" }, { Name = "Partial Eclipse", Date = "1960 Sep 20 22:59:56", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1960-09-20.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1960-09-20.gif" }, { Name = "Total Eclipse", Date = "1961 Feb 15 08:19:48", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1961-02-15.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1961-02-15.gif" }, { Name = "Annular Eclipse", Date = "1961 Aug 11 10:46:47", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1961-08-11.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1961-08-11.gif" }, { Name = "Total Eclipse", Date = "1962 Feb 05 00:12:38", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1962-02-05.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1962-02-05.gif" }, { Name = "Annular Eclipse", Date = "1962 Jul 31 12:25:33", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1962-07-31.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1962-07-31.gif" }, { Name = "Annular Eclipse", Date = "1963 Jan 25 13:37:12", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1963-01-25.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1963-01-25.gif" }, { Name = "Total Eclipse", Date = "1963 Jul 20 20:36:13", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1963-07-20.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1963-07-20.gif" }, { Name = "Partial Eclipse", Date = "1964 Jan 14 20:30:08", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1964-01-14.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1964-01-14.gif" }, { Name = "Partial Eclipse", Date = "1964 Jun 10 04:34:07", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1964-06-10.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1964-06-10.gif" }, { Name = "Partial Eclipse", Date = "1964 Jul 09 11:17:53", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1964-07-09.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1964-07-09.gif" }, { Name = "Partial Eclipse", Date = "1964 Dec 04 01:31:54", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1964-12-04.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1964-12-04.gif" }, { Name = "Total Eclipse", Date = "1965 May 30 21:17:31", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1965-05-30.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1965-05-30.gif" }, { Name = "Annular Eclipse", Date = "1965 Nov 23 04:14:51", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1965-11-23.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1965-11-23.gif" }, { Name = "Annular Eclipse", Date = "1966 May 20 09:39:02", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1966-05-20.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1966-05-20.gif" }, { Name = "Total Eclipse", Date = "1966 Nov 12 14:23:28", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1966-11-12.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1966-11-12.gif" }, { Name = "Partial Eclipse", Date = "1967 May 09 14:42:48", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1967-05-09.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1967-05-09.gif" }, { Name = "Total Eclipse", Date = "1967 Nov 02 05:38:56", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1967-11-02.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1967-11-02.gif" }, { Name = "Partial Eclipse", Date = "1968 Mar 28 23:00:30", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1968-03-28.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1968-03-28.gif" }, { Name = "Total Eclipse", Date = "1968 Sep 22 11:18:46", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1968-09-22.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1968-09-22.gif" }, { Name = "Annular Eclipse", Date = "1969 Mar 18 04:54:57", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1969-03-18.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1969-03-18.gif" }, { Name = "Annular Eclipse", Date = "1969 Sep 11 19:58:59", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1969-09-11.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1969-09-11.gif" }, { Name = "Total Eclipse", Date = "1970 Mar 07 17:38:30", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1970-03-07.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1970-03-07.gif" }, { Name = "Annular Eclipse", Date = "1970 Aug 31 21:55:30", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1970-08-31.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1970-08-31.gif" }, { Name = "Partial Eclipse", Date = "1971 Feb 25 09:38:07", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1971-02-25.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1971-02-25.gif" }, { Name = "Partial Eclipse", Date = "1971 Jul 22 09:31:55", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1971-07-22.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1971-07-22.gif" }, { Name = "Partial Eclipse", Date = "1971 Aug 20 22:39:31", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1971-08-20.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1971-08-20.gif" }, { Name = "Annular Eclipse", Date = "1972 Jan 16 11:03:22", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1972-01-16.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1972-01-16.gif" }, { Name = "Total Eclipse", Date = "1972 Jul 10 19:46:38", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1972-07-10.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1972-07-10.gif" }, { Name = "Annular Eclipse", Date = "1973 Jan 04 15:46:21", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1973-01-04.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1973-01-04.gif" }, { Name = "Total Eclipse", Date = "1973 Jun 30 11:38:41", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1973-06-30.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1973-06-30.gif" }, { Name = "Annular Eclipse", Date = "1973 Dec 24 15:02:44", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1973-12-24.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1973-12-24.gif" }, { Name = "Total Eclipse", Date = "1974 Jun 20 04:48:04", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1974-06-20.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1974-06-20.gif" }, { Name = "Partial Eclipse", Date = "1974 Dec 13 16:13:13", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1974-12-13.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1974-12-13.gif" }, { Name = "Partial Eclipse", Date = "1975 May 11 07:17:33", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1975-05-11.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1975-05-11.gif" }, { Name = "Partial Eclipse", Date = "1975 Nov 03 13:15:54", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1975-11-03.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1975-11-03.gif" }, { Name = "Annular Eclipse", Date = "1976 Apr 29 10:24:18", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1976-04-29.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1976-04-29.gif" }, { Name = "Total Eclipse", Date = "1976 Oct 23 05:13:45", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1976-10-23.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1976-10-23.gif" }, { Name = "Annular Eclipse", Date = "1977 Apr 18 10:31:30", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1977-04-18.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1977-04-18.gif" }, { Name = "Total Eclipse", Date = "1977 Oct 12 20:27:27", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1977-10-12.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1977-10-12.gif" }, { Name = "Partial Eclipse", Date = "1978 Apr 07 15:03:47", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1978-04-07.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1978-04-07.gif" }, { Name = "Partial Eclipse", Date = "1978 Oct 02 06:28:43", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1978-10-02.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1978-10-02.gif" }, { Name = "Total Eclipse", Date = "1979 Feb 26 16:55:06", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1979-02-26.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1979-02-26.gif" }, { Name = "Annular Eclipse", Date = "1979 Aug 22 17:22:38", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1979-08-22.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1979-08-22.gif" }, { Name = "Total Eclipse", Date = "1980 Feb 16 08:54:01", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1980-02-16.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1980-02-16.gif" }, { Name = "Annular Eclipse", Date = "1980 Aug 10 19:12:21", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1980-08-10.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1980-08-10.gif" }, { Name = "Annular Eclipse", Date = "1981 Feb 04 22:09:24", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1981-02-04.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1981-02-04.gif" }, { Name = "Total Eclipse", Date = "1981 Jul 31 03:46:37", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1981-07-31.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1981-07-31.gif" }, { Name = "Partial Eclipse", Date = "1982 Jan 25 04:42:53", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1982-01-25.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1982-01-25.gif" }, { Name = "Partial Eclipse", Date = "1982 Jun 21 12:04:33", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1982-06-21.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1982-06-21.gif" }, { Name = "Partial Eclipse", Date = "1982 Jul 20 18:44:44", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1982-07-20.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1982-07-20.gif" }, { Name = "Partial Eclipse", Date = "1982 Dec 15 09:32:09", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1982-12-15.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1982-12-15.gif" }, { Name = "Total Eclipse", Date = "1983 Jun 11 04:43:33", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1983-06-11.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1983-06-11.gif" }, { Name = "Annular Eclipse", Date = "1983 Dec 04 12:31:15", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1983-12-04.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1983-12-04.gif" }, { Name = "Annular Eclipse", Date = "1984 May 30 16:45:41", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1984-05-30.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1984-05-30.gif" }, { Name = "Total Eclipse", Date = "1984 Nov 22 22:54:17", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1984-11-22.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1984-11-22.gif" }, { Name = "Partial Eclipse", Date = "1985 May 19 21:29:38", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1985-05-19.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1985-05-19.gif" }, { Name = "Total Eclipse", Date = "1985 Nov 12 14:11:27", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1985-11-12.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1985-11-12.gif" }, { Name = "Partial Eclipse", Date = "1986 Apr 09 06:21:22", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1986-04-09.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1986-04-09.gif" }, { Name = "Hybrid Eclipse", Date = "1986 Oct 03 19:06:15", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1986-10-03.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1986-10-03.gif" }, { Name = "Hybrid Eclipse", Date = "1987 Mar 29 12:49:47", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1987-03-29.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1987-03-29.gif" }, { Name = "Annular Eclipse", Date = "1987 Sep 23 03:12:22", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1987-09-23.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1987-09-23.gif" }, { Name = "Total Eclipse", Date = "1988 Mar 18 01:58:56", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1988-03-18.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1988-03-18.gif" }, { Name = "Annular Eclipse", Date = "1988 Sep 11 04:44:29", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1988-09-11.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1988-09-11.gif" }, { Name = "Partial Eclipse", Date = "1989 Mar 07 18:08:41", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1989-03-07.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1989-03-07.gif" }, { Name = "Partial Eclipse", Date = "1989 Aug 31 05:31:47", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1989-08-31.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1989-08-31.gif" }, { Name = "Annular Eclipse", Date = "1990 Jan 26 19:31:24", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1990-01-26.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1990-01-26.gif" }, { Name = "Total Eclipse", Date = "1990 Jul 22 03:03:07", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1990-07-22.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1990-07-22.gif" }, { Name = "Annular Eclipse", Date = "1991 Jan 15 23:53:51", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1991-01-15.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1991-01-15.gif" }, { Name = "Total Eclipse", Date = "1991 Jul 11 19:07:01", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1991-07-11.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1991-07-11.gif" }, { Name = "Annular Eclipse", Date = "1992 Jan 04 23:05:37", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1992-01-04.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1992-01-04.gif" }, { Name = "Total Eclipse", Date = "1992 Jun 30 12:11:22", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1992-06-30.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1992-06-30.gif" }, { Name = "Partial Eclipse", Date = "1992 Dec 24 00:31:41", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1992-12-24.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1992-12-24.gif" }, { Name = "Partial Eclipse", Date = "1993 May 21 14:20:15", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1993-05-21.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1993-05-21.gif" }, { Name = "Partial Eclipse", Date = "1993 Nov 13 21:45:51", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1993-11-13.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1993-11-13.gif" }, { Name = "Annular Eclipse", Date = "1994 May 10 17:12:26", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1994-05-10.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1994-05-10.gif" }, { Name = "Total Eclipse", Date = "1994 Nov 03 13:40:06", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1994-11-03.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1994-11-03.gif" }, { Name = "Annular Eclipse", Date = "1995 Apr 29 17:33:21", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1995-04-29.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1995-04-29.gif" }, { Name = "Total Eclipse", Date = "1995 Oct 24 04:33:30", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1995-10-24.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1995-10-24.gif" }, { Name = "Partial Eclipse", Date = "1996 Apr 17 22:38:12", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1996-04-17.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1996-04-17.gif" }, { Name = "Partial Eclipse", Date = "1996 Oct 12 14:03:04", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1996-10-12.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1996-10-12.gif" }, { Name = "Total Eclipse", Date = "1997 Mar 09 01:24:51", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1997-03-09.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1997-03-09.gif" }, { Name = "Partial Eclipse", Date = "1997 Sep 02 00:04:48", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1997-09-02.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1997-09-02.gif" }, { Name = "Total Eclipse", Date = "1998 Feb 26 17:29:27", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1998-02-26.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1998-02-26.gif" }, { Name = "Annular Eclipse", Date = "1998 Aug 22 02:07:11", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1998-08-22.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1998-08-22.gif" }, { Name = "Annular Eclipse", Date = "1999 Feb 16 06:34:38", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1999-02-16.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1999-02-16.gif" }, { Name = "Total Eclipse", Date = "1999 Aug 11 11:04:09", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/1999-08-11.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/1999-08-11.gif" }, { Name = "Partial Eclipse", Date = "2000 Feb 05 12:50:27", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/2000-02-05.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2000-02-05.gif" }, { Name = "Partial Eclipse", Date = "2000 Jul 01 19:33:34", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/2000-07-01.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2000-07-01.gif" }, { Name = "Partial Eclipse", Date = "2000 Jul 31 02:14:08", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/2000-07-31.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2000-07-31.gif" }, { Name = "Partial Eclipse", Date = "2000 Dec 25 17:35:57", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/1901-2000/2000-12-25.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2000-12-25.gif" }, { Name = "Total Eclipse", Date = "2001 Jun 21 12:04:46", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2001-06-21.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2001-06-21.gif" }, { Name = "Annular Eclipse", Date = "2001 Dec 14 20:53:01", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2001-12-14.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2001-12-14.gif" }, { Name = "Annular Eclipse", Date = "2002 Jun 10 23:45:22", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2002-06-10.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2002-06-10.gif" }, { Name = "Total Eclipse", Date = "2002 Dec 04 07:32:16", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2002-12-04.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2002-12-04.gif" }, { Name = "Annular Eclipse", Date = "2003 May 31 04:09:22", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2003-05-31.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2003-05-31.gif" }, { Name = "Total Eclipse", Date = "2003 Nov 23 22:50:22", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2003-11-23.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2003-11-23.gif" }, { Name = "Partial Eclipse", Date = "2004 Apr 19 13:35:05", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2004-04-19.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2004-04-19.gif" }, { Name = "Partial Eclipse", Date = "2004 Oct 14 03:00:23", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2004-10-14.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2004-10-14.gif" }, { Name = "Hybrid Eclipse", Date = "2005 Apr 08 20:36:51", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2005-04-08.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2005-04-08.gif" }, { Name = "Annular Eclipse", Date = "2005 Oct 03 10:32:47", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2005-10-03.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2005-10-03.gif" }, { Name = "Total Eclipse", Date = "2006 Mar 29 10:12:23", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2006-03-29.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2006-03-29.gif" }, { Name = "Annular Eclipse", Date = "2006 Sep 22 11:41:16", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2006-09-22.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2006-09-22.gif" }, { Name = "Partial Eclipse", Date = "2007 Mar 19 02:32:57", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2007-03-19.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2007-03-19.gif" }, { Name = "Partial Eclipse", Date = "2007 Sep 11 12:32:24", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2007-09-11.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2007-09-11.gif" }, { Name = "Annular Eclipse", Date = "2008 Feb 07 03:56:10", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2008-02-07.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2008-02-07.gif" }, { Name = "Total Eclipse", Date = "2008 Aug 01 10:22:12", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2008-08-01.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2008-08-01.gif" }, { Name = "Annular Eclipse", Date = "2009 Jan 26 07:59:45", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2009-01-26.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2009-01-26.gif" }, { Name = "Total Eclipse", Date = "2009 Jul 22 02:36:25", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2009-07-22.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2009-07-22.gif" }, { Name = "Annular Eclipse", Date = "2010 Jan 15 07:07:39", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2010-01-15.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2010-01-15.gif" }, { Name = "Total Eclipse", Date = "2010 Jul 11 19:34:38", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2010-07-11.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2010-07-11.gif" }, { Name = "Partial Eclipse", Date = "2011 Jan 04 08:51:4", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2011-01-04.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2011-01-04.gif" }, { Name = "Partial Eclipse", Date = "2011 Jun 01 21:17:18", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2011-06-01.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2011-06-01.gif" }, { Name = "Partial Eclipse", Date = "2011 Jul 01 08:39:30", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2011-07-01.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2011-07-01.gif" }, { Name = "Partial Eclipse", Date = "2011 Nov 25 06:21:24", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2011-11-25.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2011-11-25.gif" }, { Name = "Annular Eclipse", Date = "2012 May 20 23:53:54", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2012-05-20.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2012-05-20.gif" }, { Name = "Total Eclipse", Date = "2012 Nov 13 22:12:55", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2012-11-13.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2012-11-13.gif" }, { Name = "Annular Eclipse", Date = "2013 May 10 00:26:20", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2013-05-10.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2013-05-10.gif" }, { Name = "Hybrid Eclipse", Date = "2013 Nov 03 12:47:36", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2013-11-03.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2013-11-03.gif" }, { Name = "Annular Eclipse", Date = "2014 Apr 29 06:04:33", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2014-04-29.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2014-04-29.gif" }, { Name = "Partial Eclipse", Date = "2014 Oct 23 21:45:39", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2014-10-23.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2014-10-23.gif" }, { Name = "Total Eclipse", Date = "2015 Mar 20 09:46:47", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2015-03-20.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2015-03-20.gif" }, { Name = "Partial Eclipse", Date = "2015 Sep 13 06:55:19", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2015-09-13.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2015-09-13.gif" }, { Name = "Total Eclipse", Date = "2016 Mar 09 01:58:19", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2016-03-09.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2016-03-09.gif" }, { Name = "Annular Eclipse", Date = "2016 Sep 01 09:08:02", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2016-09-01.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2016-09-01.gif" }, { Name = "Annular Eclipse", Date = "2017 Feb 26 14:54:33", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2017-02-26.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2017-02-26.gif" }, { Name = "Total Eclipse", Date = "2017 Aug 21 18:26:40", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2017-08-21.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2017-08-21.gif" }, { Name = "Partial Eclipse", Date = "2018 Feb 15 20:52:33", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2018-02-15.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2018-02-15.gif" }, { Name = "Partial Eclipse", Date = "2018 Jul 13 03:02:16", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2018-07-13.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2018-07-13.gif" }, { Name = "Partial Eclipse", Date = "2018 Aug 11 09:47:28", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2018-08-11.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2018-08-11.gif" }, { Name = "Partial Eclipse", Date = "2019 Jan 06 01:42:38", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2019-01-06.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2019-01-06.gif" }, { Name = "Total Eclipse", Date = "2019 Jul 02 19:24:07", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2019-07-02.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2019-07-02.gif" }, { Name = "Annular Eclipse", Date = "2019 Dec 26 05:18:53", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2019-12-26.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2019-12-26.gif" }, { Name = "Annular Eclipse", Date = "2020 Jun 21 06:41:15", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2020-06-21.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2020-06-21.gif" }, { Name = "Total Eclipse", Date = "2020 Dec 14 16:14:39", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2020-12-14.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2020-12-14.gif" }, { Name = "Annular Eclipse", Date = "2021 Jun 10 10:43:07", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2021-06-10.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2021-06-10.gif" }, { Name = "Total Eclipse", Date = "2021 Dec 04 07:34:38", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2021-12-04.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2021-12-04.gif" }, { Name = "Partial Eclipse", Date = "2022 Apr 30 20:42:36", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2022-04-30.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2022-04-30.gif" }, { Name = "Partial Eclipse", Date = "2022 Oct 25 11:01:20", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2022-10-25.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2022-10-25.gif" }, { Name = "Hybrid Eclipse", Date = "2023 Apr 20 04:17:56", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2023-04-20.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2023-04-20.gif" }, { Name = "Annular Eclipse", Date = "2023 Oct 14 18:00:41", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2023-10-14.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2023-10-14.gif" }, { Name = "Total Eclipse", Date = "2024 Apr 08 18:18:29", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2024-04-08.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2024-04-08.gif" }, { Name = "Annular Eclipse", Date = "2024 Oct 02 18:46:13", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2024-10-02.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2024-10-02.gif" }, { Name = "Partial Eclipse", Date = "2025 Mar 29 10:48:36", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2025-03-29.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2025-03-29.gif" }, { Name = "Partial Eclipse", Date = "2025 Sep 21 19:43:04", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2025-09-21.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2025-09-21.gif" }, { Name = "Annular Eclipse", Date = "2026 Feb 17 12:13:06", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2026-02-17.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2026-02-17.gif" }, { Name = "Total Eclipse", Date = "2026 Aug 12 17:47:06", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2026-08-12.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2026-08-12.gif" }, { Name = "Annular Eclipse", Date = "2027 Feb 06 16:00:48", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2027-02-06.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2027-02-06.gif" }, { Name = "Total Eclipse", Date = "2027 Aug 02 10:07:50", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2027-08-02.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2027-08-02.gif" }, { Name = "Annular Eclipse", Date = "2028 Jan 26 15:08:59", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2028-01-26.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2028-01-26.gif" }, { Name = "Total Eclipse", Date = "2028 Jul 22 02:56:40", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2028-07-22.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2028-07-22.gif" }, { Name = "Partial Eclipse", Date = "2029 Jan 14 17:13:48", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2029-01-14.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2029-01-14.gif" }, { Name = "Partial Eclipse", Date = "2029 Jun 12 04:06:13", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2029-06-12.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2029-06-12.gif" }, { Name = "Partial Eclipse", Date = "2029 Jul 11 15:37:19", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2029-07-11.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2029-07-11.gif" }, { Name = "Partial Eclipse", Date = "2029 Dec 05 15:03:58", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2029-12-05.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2029-12-05.gif" }, { Name = "Annular Eclipse", Date = "2030 Jun 01 06:29:13", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2030-06-01.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2030-06-01.gif" }, { Name = "Total Eclipse", Date = "2030 Nov 25 06:51:37", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2030-11-25.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2030-11-25.gif" }, { Name = "Annular Eclipse", Date = "2031 May 21 07:16:04", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2031-05-21.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2031-05-21.gif" }, { Name = "Hybrid Eclipse", Date = "2031 Nov 14 21:07:31", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2031-11-14.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2031-11-14.gif" }, { Name = "Annular Eclipse", Date = "2032 May 09 13:26:42", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2032-05-09.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2032-05-09.gif" }, { Name = "Partial Eclipse", Date = "2032 Nov 03 05:34:13", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2032-11-03.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2032-11-03.gif" }, { Name = "Total Eclipse", Date = "2033 Mar 30 18:02:36", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2033-03-30.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2033-03-30.gif" }, { Name = "Partial Eclipse", Date = "2033 Sep 23 13:54:31", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2033-09-23.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2033-09-23.gif" }, { Name = "Total Eclipse", Date = "2034 Mar 20 10:18:45", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2034-03-20.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2034-03-20.gif" }, { Name = "Annular Eclipse", Date = "2034 Sep 12 16:19:28", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2034-09-12.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2034-09-12.gif" }, { Name = "Annular Eclipse", Date = "2035 Mar 09 23:05:54", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2035-03-09.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2035-03-09.gif" }, { Name = "Total Eclipse", Date = "2035 Sep 02 01:56:46", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2035-09-02.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2035-09-02.gif" }, { Name = "Partial Eclipse", Date = "2036 Feb 27 04:46:49", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2036-02-27.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2036-02-27.gif" }, { Name = "Partial Eclipse", Date = "2036 Jul 23 10:32:06", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2036-07-23.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2036-07-23.gif" }, { Name = "Partial Eclipse", Date = "2036 Aug 21 17:25:45", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2036-08-21.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2036-08-21.gif" }, { Name = "Partial Eclipse", Date = "2037 Jan 16 09:48:55", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2037-01-16.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2037-01-16.gif" }, { Name = "Total Eclipse", Date = "2037 Jul 13 02:40:36", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2037-07-13.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2037-07-13.gif" }, { Name = "Annular Eclipse", Date = "2038 Jan 05 13:47:11", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2038-01-05.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2038-01-05.gif" }, { Name = "Annular Eclipse", Date = "2038 Jul 02 13:32:55", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2038-07-02.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2038-07-02.gif" }, { Name = "Total Eclipse", Date = "2038 Dec 26 01:00:10", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2038-12-26.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2038-12-26.gif" }, { Name = "Annular Eclipse", Date = "2039 Jun 21 17:12:54", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2039-06-21.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2039-06-21.gif" }, { Name = "Total Eclipse", Date = "2039 Dec 15 16:23:46", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2039-12-15.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2039-12-15.gif" }, { Name = "Partial Eclipse", Date = "2040 May 11 03:43:02", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2040-05-11.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2040-05-11.gif" }, { Name = "Partial Eclipse", Date = "2040 Nov 04 19:09:02", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2040-11-04.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2040-11-04.gif" }, { Name = "Total Eclipse", Date = "2041 Apr 30 11:52:21", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2041-04-30.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2041-04-30.gif" }, { Name = "Annular Eclipse", Date = "2041 Oct 25 01:36:22", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2041-10-25.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2041-10-25.gif" }, { Name = "Total Eclipse", Date = "2042 Apr 20 02:17:30", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2042-04-20.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2042-04-20.gif" }, { Name = "Annular Eclipse", Date = "2042 Oct 14 02:00:42", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2042-10-14.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2042-10-14.gif" }, { Name = "Total Eclipse", Date = "2043 Apr 09 18:57:49", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2043-04-09.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2043-04-09.gif" }, { Name = "Annular Eclipse", Date = "2043 Oct 03 03:01:49", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2043-10-03.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2043-10-03.gif" }, { Name = "Annular Eclipse", Date = "2044 Feb 28 20:24:39", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2044-02-28.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2044-02-28.gif" }, { Name = "Total Eclipse", Date = "2044 Aug 23 01:17:02", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2044-08-23.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2044-08-23.gif" }, { Name = "Annular Eclipse", Date = "2045 Feb 16 23:56:07", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2045-02-16.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2045-02-16.gif" }, { Name = "Total Eclipse", Date = "2045 Aug 12 17:42:39", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2045-08-12.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2045-08-12.gif" }, { Name = "Annular Eclipse", Date = "2046 Feb 05 23:06:26", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2046-02-05.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2046-02-05.gif" }, { Name = "Total Eclipse", Date = "2046 Aug 02 10:21:13", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2046-08-02.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2046-08-02.gif" }, { Name = "Partial Eclipse", Date = "2047 Jan 26 01:33:18", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2047-01-26.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2047-01-26.gif" }, { Name = "Partial Eclipse", Date = "2047 Jun 23 10:52:31", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2047-06-23.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2047-06-23.gif" }, { Name = "Partial Eclipse", Date = "2047 Jul 22 22:36:17", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2047-07-22.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2047-07-22.gif" }, { Name = "Partial Eclipse", Date = "2047 Dec 16 23:50:12", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2047-12-16.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2047-12-16.gif" }, { Name = "Annular Eclipse", Date = "2048 Jun 11 12:58:53", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2048-06-11.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2048-06-11.gif" }, { Name = "Total Eclipse", Date = "2048 Dec 05 15:35:27", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2048-12-05.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2048-12-05.gif" }, { Name = "Annular Eclipse", Date = "2049 May 31 13:59:59", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2049-05-31.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2049-05-31.gif" }, { Name = "Hybrid Eclipse", Date = "2049 Nov 25 05:33:48", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2049-11-25.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2049-11-25.gif" }, { Name = "Hybrid Eclipse", Date = "2050 May 20 20:42:50", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2050-05-20.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2050-05-20.gif" }, { Name = "Partial Eclipse", Date = "2050 Nov 14 13:30:53", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2050-11-14.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2050-11-14.gif" }, { Name = "Partial Eclipse", Date = "2051 Apr 11 02:10:39", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2051-04-11.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2051-04-11.gif" }, { Name = "Partial Eclipse", Date = "2051 Oct 04 21:02:14", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2051-10-04.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2051-10-04.gif" }, { Name = "Total Eclipse", Date = "2052 Mar 30 18:31:53", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2052-03-30.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2052-03-30.gif" }, { Name = "Annular Eclipse", Date = "2052 Sep 22 23:39:10", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2052-09-22.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2052-09-22.gif" }, { Name = "Annular Eclipse", Date = "2053 Mar 20 07:08:19", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2053-03-20.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2053-03-20.gif" }, { Name = "Total Eclipse", Date = "2053 Sep 12 09:34:09", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2053-09-12.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2053-09-12.gif" }, { Name = "Partial Eclipse", Date = "2054 Mar 09 12:33:40", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2054-03-09.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2054-03-09.gif" }, { Name = "Partial Eclipse", Date = "2054 Aug 03 18:04:02", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2054-08-03.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2054-08-03.gif" }, { Name = "Partial Eclipse", Date = "2054 Sep 02 01:09:34", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2054-09-02.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2054-09-02.gif" }, { Name = "Partial Eclipse", Date = "2055 Jan 27 17:54:05", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2055-01-27.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2055-01-27.gif" }, { Name = "Total Eclipse", Date = "2055 Jul 24 09:57:50", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2055-07-24.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2055-07-24.gif" }, { Name = "Annular Eclipse", Date = "2056 Jan 16 22:16:45", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2056-01-16.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2056-01-16.gif" }, { Name = "Annular Eclipse", Date = "2056 Jul 12 20:21:59", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2056-07-12.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2056-07-12.gif" }, { Name = "Total Eclipse", Date = "2057 Jan 05 09:47:52", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2057-01-05.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2057-01-05.gif" }, { Name = "Annular Eclipse", Date = "2057 Jul 01 23:40:15", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2057-07-01.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2057-07-01.gif" }, { Name = "Total Eclipse", Date = "2057 Dec 26 01:14:35", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2057-12-26.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2057-12-26.gif" }, { Name = "Partial Eclipse", Date = "2058 May 22 10:39:25", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2058-05-22.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2058-05-22.gif" }, { Name = "Partial Eclipse", Date = "2058 Jun 21 00:19:35", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2058-06-21.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2058-06-21.gif" }, { Name = "Partial Eclipse", Date = "2058 Nov 16 03:23:07", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2058-11-16.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2058-11-16.gif" }, { Name = "Total Eclipse", Date = "2059 May 11 19:22:16", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2059-05-11.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2059-05-11.gif" }, { Name = "Annular Eclipse", Date = "2059 Nov 05 09:18:15", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2059-11-05.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2059-11-05.gif" }, { Name = "Total Eclipse", Date = "2060 Apr 30 10:10:00", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2060-04-30.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2060-04-30.gif" }, { Name = "Annular Eclipse", Date = "2060 Oct 24 09:24:10", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2060-10-24.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2060-10-24.gif" }, { Name = "Total Eclipse", Date = "2061 Apr 20 02:56:49", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2061-04-20.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2061-04-20.gif" }, { Name = "Annular Eclipse", Date = "2061 Oct 13 10:32:10", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2061-10-13.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2061-10-13.gif" }, { Name = "Partial Eclipse", Date = "2062 Mar 11 04:26:16", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2062-03-11.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2062-03-11.gif" }, { Name = "Partial Eclipse", Date = "2062 Sep 03 08:54:27", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2062-09-03.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2062-09-03.gif" }, { Name = "Annular Eclipse", Date = "2063 Feb 28 07:43:30", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2063-02-28.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2063-02-28.gif" }, { Name = "Total Eclipse", Date = "2063 Aug 24 01:22:11", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2063-08-24.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2063-08-24.gif" }, { Name = "Annular Eclipse", Date = "2064 Feb 17 07:00:23", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2064-02-17.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2064-02-17.gif" }, { Name = "Total Eclipse", Date = "2064 Aug 12 17:46:06", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2064-08-12.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2064-08-12.gif" }, { Name = "Partial Eclipse", Date = "2065 Feb 05 09:52:26", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2065-02-05.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2065-02-05.gif" }, { Name = "Partial Eclipse", Date = "2065 Jul 03 17:33:52", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2065-07-03.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2065-07-03.gif" }, { Name = "Partial Eclipse", Date = "2065 Aug 02 05:34:17", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2065-08-02.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2065-08-02.gif" }, { Name = "Partial Eclipse", Date = "2065 Dec 27 08:39:56", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2065-12-27.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2065-12-27.gif" }, { Name = "Annular Eclipse", Date = "2066 Jun 22 19:25:48", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2066-06-22.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2066-06-22.gif" }, { Name = "Total Eclipse", Date = "2066 Dec 17 00:23:40", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2066-12-17.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2066-12-17.gif" }, { Name = "Annular Eclipse", Date = "2067 Jun 11 20:42:26", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2067-06-11.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2067-06-11.gif" }, { Name = "Hybrid Eclipse", Date = "2067 Dec 06 14:03:43", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2067-12-06.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2067-12-06.gif" }, { Name = "Total Eclipse", Date = "2068 May 31 03:56:39", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2068-05-31.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2068-05-31.gif" }, { Name = "Partial Eclipse", Date = "2068 Nov 24 21:32:30", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2068-11-24.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2068-11-24.gif" }, { Name = "Partial Eclipse", Date = "2069 Apr 21 10:11:09", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2069-04-21.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2069-04-21.gif" }, { Name = "Partial Eclipse", Date = "2069 May 20 17:53:18", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2069-05-20.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2069-05-20.gif" }, { Name = "Partial Eclipse", Date = "2069 Oct 15 04:19:56", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2069-10-15.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2069-10-15.gif" }, { Name = "Total Eclipse", Date = "2070 Apr 11 02:36:09", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2070-04-11.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2070-04-11.gif" }, { Name = "Annular Eclipse", Date = "2070 Oct 04 07:08:57", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2070-10-04.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2070-10-04.gif" }, { Name = "Annular Eclipse", Date = "2071 Mar 31 15:01:06", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2071-03-31.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2071-03-31.gif" }, { Name = "Total Eclipse", Date = "2071 Sep 23 17:20:28", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2071-09-23.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2071-09-23.gif" }, { Name = "Partial Eclipse", Date = "2072 Mar 19 20:10:31", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2072-03-19.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2072-03-19.gif" }, { Name = "Total Eclipse", Date = "2072 Sep 12 08:59:20", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2072-09-12.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2072-09-12.gif" }, { Name = "Partial Eclipse", Date = "2073 Feb 07 01:55:59", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2073-02-07.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2073-02-07.gif" }, { Name = "Total Eclipse", Date = "2073 Aug 03 17:15:23", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2073-08-03.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2073-08-03.gif" }, { Name = "Annular Eclipse", Date = "2074 Jan 27 06:44:15", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2074-01-27.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2074-01-27.gif" }, { Name = "Annular Eclipse", Date = "2074 Jul 24 03:10:32", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2074-07-24.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2074-07-24.gif" }, { Name = "Total Eclipse", Date = "2075 Jan 16 18:36:04", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2075-01-16.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2075-01-16.gif" }, { Name = "Annular Eclipse", Date = "2075 Jul 13 06:05:44", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2075-07-13.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2075-07-13.gif" }, { Name = "Total Eclipse", Date = "2076 Jan 06 10:07:27", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2076-01-06.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2076-01-06.gif" }, { Name = "Partial Eclipse", Date = "2076 Jun 01 17:31:22", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2076-06-01.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2076-06-01.gif" }, { Name = "Partial Eclipse", Date = "2076 Jul 01 06:50:43", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2076-07-01.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2076-07-01.gif" }, { Name = "Partial Eclipse", Date = "2076 Nov 26 11:43:01", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2076-11-26.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2076-11-26.gif" }, { Name = "Total Eclipse", Date = "2077 May 22 02:46:05", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2077-05-22.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2077-05-22.gif" }, { Name = "Annular Eclipse", Date = "2077 Nov 15 17:07:56", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2077-11-15.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2077-11-15.gif" }, { Name = "Total Eclipse", Date = "2078 May 11 17:56:55", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2078-05-11.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2078-05-11.gif" }, { Name = "Annular Eclipse", Date = "2078 Nov 04 16:55:44", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2078-11-04.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2078-11-04.gif" }, { Name = "Total Eclipse", Date = "2079 May 01 10:50:13", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2079-05-01.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2079-05-01.gif" }, { Name = "Annular Eclipse", Date = "2079 Oct 24 18:11:21", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2079-10-24.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2079-10-24.gif" }, { Name = "Partial Eclipse", Date = "2080 Mar 21 12:20:15", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2080-03-21.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2080-03-21.gif" }, { Name = "Partial Eclipse", Date = "2080 Sep 13 16:38:09", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2080-09-13.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2080-09-13.gif" }, { Name = "Annular Eclipse", Date = "2081 Mar 10 15:23:31", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2081-03-10.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2081-03-10.gif" }, { Name = "Total Eclipse", Date = "2081 Sep 03 09:07:31", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2081-09-03.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2081-09-03.gif" }, { Name = "Annular Eclipse", Date = "2082 Feb 27 14:47:00", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2082-02-27.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2082-02-27.gif" }, { Name = "Total Eclipse", Date = "2082 Aug 24 01:16:21", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2082-08-24.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2082-08-24.gif" }, { Name = "Partial Eclipse", Date = "2083 Feb 16 18:06:36", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2083-02-16.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2083-02-16.gif" }, { Name = "Partial Eclipse", Date = "2083 Jul 15 00:14:23", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2083-07-15.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2083-07-15.gif" }, { Name = "Partial Eclipse", Date = "2083 Aug 13 12:34:41", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2083-08-13.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2083-08-13.gif" }, { Name = "Partial Eclipse", Date = "2084 Jan 07 17:30:24", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2084-01-07.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2084-01-07.gif" }, { Name = "Annular Eclipse", Date = "2084 Jul 03 01:50:26", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2084-07-03.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2084-07-03.gif" }, { Name = "Total Eclipse", Date = "2084 Dec 27 09:13:48", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2084-12-27.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2084-12-27.gif" }, { Name = "Annular Eclipse", Date = "2085 Jun 22 03:21:16", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2085-06-22.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2085-06-22.gif" }, { Name = "Annular Eclipse", Date = "2085 Dec 16 22:37:48", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2085-12-16.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2085-12-16.gif" }, { Name = "Total Eclipse", Date = "2086 Jun 11 11:07:14", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2086-06-11.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2086-06-11.gif" }, { Name = "Partial Eclipse", Date = "2086 Dec 06 05:38:55", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2086-12-06.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2086-12-06.gif" }, { Name = "Partial Eclipse", Date = "2087 May 02 18:04:42", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2087-05-02.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2087-05-02.gif" }, { Name = "Partial Eclipse", Date = "2087 Jun 01 01:27:14", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2087-06-01.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2087-06-01.gif" }, { Name = "Partial Eclipse", Date = "2087 Oct 26 11:46:57", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2087-10-26.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2087-10-26.gif" }, { Name = "Total Eclipse", Date = "2088 Apr 21 10:31:49", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2088-04-21.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2088-04-21.gif" }, { Name = "Annular Eclipse", Date = "2088 Oct 14 14:48:05", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2088-10-14.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2088-10-14.gif" }, { Name = "Annular Eclipse", Date = "2089 Apr 10 22:44:42", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2089-04-10.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2089-04-10.gif" }, { Name = "Total Eclipse", Date = "2089 Oct 04 01:15:23", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2089-10-04.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2089-10-04.gif" }, { Name = "Partial Eclipse", Date = "2090 Mar 31 03:38:08", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2090-03-31.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2090-03-31.gif" }, { Name = "Total Eclipse", Date = "2090 Sep 23 16:56:36", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2090-09-23.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2090-09-23.gif" }, { Name = "Partial Eclipse", Date = "2091 Feb 18 09:54:40", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2091-02-18.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2091-02-18.gif" }, { Name = "Total Eclipse", Date = "2091 Aug 15 00:34:43", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2091-08-15.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2091-08-15.gif" }, { Name = "Annular Eclipse", Date = "2092 Feb 07 15:10:20", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2092-02-07.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2092-02-07.gif" }, { Name = "Annular Eclipse", Date = "2092 Aug 03 09:59:33", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2092-08-03.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2092-08-03.gif" }, { Name = "Total Eclipse", Date = "2093 Jan 27 03:22:16", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2093-01-27.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2093-01-27.gif" }, { Name = "Annular Eclipse", Date = "2093 Jul 23 12:32:04", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2093-07-23.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2093-07-23.gif" }, { Name = "Total Eclipse", Date = "2094 Jan 16 18:59:03", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2094-01-16.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2094-01-16.gif" }, { Name = "Partial Eclipse", Date = "2094 Jun 13 00:22:11", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2094-06-13.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2094-06-13.gif" }, { Name = "Partial Eclipse", Date = "2094 Jul 12 13:24:35", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2094-07-12.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2094-07-12.gif" }, { Name = "Partial Eclipse", Date = "2094 Dec 07 20:05:56", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2094-12-07.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2094-12-07.gif" }, { Name = "Total Eclipse", Date = "2095 Jun 02 10:07:40", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2095-06-02.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2095-06-02.gif" }, { Name = "Annular Eclipse", Date = "2095 Nov 27 01:02:57", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2095-11-27.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2095-11-27.gif" }, { Name = "Total Eclipse", Date = "2096 May 22 01:37:14", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2096-05-22.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2096-05-22.gif" }, { Name = "Annular Eclipse", Date = "2096 Nov 15 00:36:15", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2096-11-15.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2096-11-15.gif" }, { Name = "Total Eclipse", Date = "2097 May 11 18:34:31", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2097-05-11.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2097-05-11.gif" }, { Name = "Annular Eclipse", Date = "2097 Nov 04 02:01:25", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2097-11-04.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2097-11-04.gif" }, { Name = "Partial Eclipse", Date = "2098 Apr 01 20:02:31", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2098-04-01.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2098-04-01.gif" }, { Name = "Partial Eclipse", Date = "2098 Sep 25 00:31:16", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2098-09-25.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2098-09-25.gif" }, { Name = "Partial Eclipse", Date = "2098 Oct 24 10:36:11", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2098-10-24.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2098-10-24.gif" }, { Name = "Annular Eclipse", Date = "2099 Mar 21 22:54:32", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2099-03-21.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2099-03-21.gif" }, { Name = "Total Eclipse", Date = "2099 Sep 14 16:57:53", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2099-09-14.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2099-09-14.gif" }, { Name = "Annular Eclipse", Date = "2100 Mar 10 22:28:11", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2100-03-10.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2100-03-10.gif" }, { Name = "Total Eclipse", Date = "2100 Sep 04 08:49:20", - Image = "https://eclipse.gsfc.nasa.gov/5MCSEmap/2001-2100/2100-09-04.gif" + Image = "https://data.openspaceproject.com/missions/eclipses/2100-09-04.gif" } } } diff --git a/data/assets/scene/solarsystem/planets/earth/grids.asset b/data/assets/scene/solarsystem/planets/earth/grids.asset index 64857f4652..62dd7020b0 100644 --- a/data/assets/scene/solarsystem/planets/earth/grids.asset +++ b/data/assets/scene/solarsystem/planets/earth/grids.asset @@ -36,7 +36,8 @@ local plane1lsec = { }, GUI = { Name = "1lsec Grid", - Path = "/Solar System/Planets/Earth" + Path = "/Solar System/Planets/Earth", + Focusable = false } } @@ -64,7 +65,8 @@ local plane1lmin = { }, GUI = { Name = "1lmin Grid", - Path = "/Solar System/Planets/Earth" + Path = "/Solar System/Planets/Earth", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/lagrange_points/l1/l1.asset b/data/assets/scene/solarsystem/planets/earth/lagrange_points/l1/l1.asset index c1806432eb..3071c334a5 100644 --- a/data/assets/scene/solarsystem/planets/earth/lagrange_points/l1/l1.asset +++ b/data/assets/scene/solarsystem/planets/earth/lagrange_points/l1/l1.asset @@ -46,6 +46,7 @@ local L1Label = { GUI = { Name = "L1 Label", Path = "/Solar System/Planets/Earth/Lagrange Points", + Focusable = false, Description = "Main label for L1" } } diff --git a/data/assets/scene/solarsystem/planets/earth/lagrange_points/l2/l2.asset b/data/assets/scene/solarsystem/planets/earth/lagrange_points/l2/l2.asset index 4ae51aa794..30bfcd5609 100644 --- a/data/assets/scene/solarsystem/planets/earth/lagrange_points/l2/l2.asset +++ b/data/assets/scene/solarsystem/planets/earth/lagrange_points/l2/l2.asset @@ -64,6 +64,7 @@ local L2SmallLabel = { GUI = { Name = "L2 Small Label", Path = "/Solar System/Planets/Earth/Lagrange Points", + Focusable = false, Description = "Small label for L2" } } @@ -86,6 +87,7 @@ local L2Label = { GUI = { Name = "L2 Label", Path = "/Solar System/Planets/Earth/Lagrange Points", + Focusable = false, Description = "Main label for L2" } } diff --git a/data/assets/scene/solarsystem/planets/earth/lagrange_points/l2/l2sunline.asset b/data/assets/scene/solarsystem/planets/earth/lagrange_points/l2/l2sunline.asset index 16c3bb83ba..8af3a8080c 100644 --- a/data/assets/scene/solarsystem/planets/earth/lagrange_points/l2/l2sunline.asset +++ b/data/assets/scene/solarsystem/planets/earth/lagrange_points/l2/l2sunline.asset @@ -18,7 +18,8 @@ local L2SunLine = { Tag = { "lagrange_points_earth_l2_small" }, GUI = { Name = "Sun to L2 Line", - Path = "/Solar System/Planets/Earth/Lagrange Points" + Path = "/Solar System/Planets/Earth/Lagrange Points", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/lagrange_points/l2/transforms.asset b/data/assets/scene/solarsystem/planets/earth/lagrange_points/l2/transforms.asset index 2fc0f468ee..bac618b7f3 100644 --- a/data/assets/scene/solarsystem/planets/earth/lagrange_points/l2/transforms.asset +++ b/data/assets/scene/solarsystem/planets/earth/lagrange_points/l2/transforms.asset @@ -18,6 +18,7 @@ local L2Position = { GUI = { Name = "L2 Position", Path = "/Solar System/Planets/Earth/Lagrange Points", + Focusable = false, Hidden = true } } @@ -38,6 +39,7 @@ local L2CoRevFrame = { GUI = { Name = "L2 Co-revolving Reference Frame", Path = "/Solar System/Planets/Earth/Lagrange Points", + Focusable = false, Hidden = true } } diff --git a/data/assets/scene/solarsystem/planets/earth/lagrange_points/l4/l4.asset b/data/assets/scene/solarsystem/planets/earth/lagrange_points/l4/l4.asset index 7dda9ff4e9..c3f775e389 100644 --- a/data/assets/scene/solarsystem/planets/earth/lagrange_points/l4/l4.asset +++ b/data/assets/scene/solarsystem/planets/earth/lagrange_points/l4/l4.asset @@ -46,6 +46,7 @@ local L4Label = { GUI = { Name = "L4 Label", Path = "/Solar System/Planets/Earth/Lagrange Points", + Focusable = false, Description = "Main label for L4" } } diff --git a/data/assets/scene/solarsystem/planets/earth/lagrange_points/l4/transforms.asset b/data/assets/scene/solarsystem/planets/earth/lagrange_points/l4/transforms.asset index 9bf6a983e9..b9209795b8 100644 --- a/data/assets/scene/solarsystem/planets/earth/lagrange_points/l4/transforms.asset +++ b/data/assets/scene/solarsystem/planets/earth/lagrange_points/l4/transforms.asset @@ -18,6 +18,7 @@ local L4Position = { GUI = { Name = "L4 Position", Path = "/Solar System/Planets/Earth/Lagrange Points", + Focusable = false, Hidden = true } } diff --git a/data/assets/scene/solarsystem/planets/earth/lagrange_points/l5/l5.asset b/data/assets/scene/solarsystem/planets/earth/lagrange_points/l5/l5.asset index a7f71a277c..fa71ad688f 100644 --- a/data/assets/scene/solarsystem/planets/earth/lagrange_points/l5/l5.asset +++ b/data/assets/scene/solarsystem/planets/earth/lagrange_points/l5/l5.asset @@ -46,6 +46,7 @@ local L5Label = { GUI = { Name = "L5 Label", Path = "/Solar System/Planets/Earth/Lagrange Points", + Focusable = false, Description = "Main label for L5" } } diff --git a/data/assets/scene/solarsystem/planets/earth/lagrange_points/l5/transforms.asset b/data/assets/scene/solarsystem/planets/earth/lagrange_points/l5/transforms.asset index fef44db03d..0275695791 100644 --- a/data/assets/scene/solarsystem/planets/earth/lagrange_points/l5/transforms.asset +++ b/data/assets/scene/solarsystem/planets/earth/lagrange_points/l5/transforms.asset @@ -18,6 +18,7 @@ local L5Position = { GUI = { Name = "L5 Position", Path = "/Solar System/Planets/Earth/Lagrange Points", + Focusable = false, Hidden = true } } diff --git a/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/blue_marble.asset b/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/blue_marble.asset index 6c0d330505..86656eccc1 100644 --- a/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/blue_marble.asset +++ b/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/blue_marble.asset @@ -16,8 +16,7 @@ local Layer = { Enabled = asset.enabled, ZIndex = 5, FilePath = texturesPath .. "earth_bluemarble.jpg", - Description = "Earth image from Blue Marble Next Generation", - CacheSettings = { Enabled = false } + Description = "Earth image from Blue Marble Next Generation" } diff --git a/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/esri_world_imagery.wms b/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/esri_world_imagery.wms index 5b2de30119..ab2a08d702 100644 --- a/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/esri_world_imagery.wms +++ b/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/esri_world_imagery.wms @@ -7,7 +7,7 @@ 90 180 -90 - 19 + 21 2 1 top diff --git a/data/assets/scene/solarsystem/planets/earth/layers/heightlayers/blue_marble_height.asset b/data/assets/scene/solarsystem/planets/earth/layers/heightlayers/blue_marble_height.asset index 9b8433f619..0c9c80eccc 100644 --- a/data/assets/scene/solarsystem/planets/earth/layers/heightlayers/blue_marble_height.asset +++ b/data/assets/scene/solarsystem/planets/earth/layers/heightlayers/blue_marble_height.asset @@ -21,8 +21,7 @@ local Layer = { Settings = { Multiplier = 40, Offset = -600 - }, - CacheSettings = { Enabled = false } + } } diff --git a/data/assets/scene/solarsystem/planets/earth/layers/heightlayers/terrain_tileset.wms b/data/assets/scene/solarsystem/planets/earth/layers/heightlayers/terrain_tileset.wms index 4c910a7cbd..a2d1f631b4 100644 --- a/data/assets/scene/solarsystem/planets/earth/layers/heightlayers/terrain_tileset.wms +++ b/data/assets/scene/solarsystem/planets/earth/layers/heightlayers/terrain_tileset.wms @@ -17,7 +17,7 @@ 512 1 Float32 - + 5 404,400 diff --git a/data/assets/scene/solarsystem/planets/earth/layers/nightlayers/earth_at_night_temporal.asset b/data/assets/scene/solarsystem/planets/earth/layers/nightlayers/earth_at_night_temporal.asset index 9335950d43..2393388b27 100644 --- a/data/assets/scene/solarsystem/planets/earth/layers/nightlayers/earth_at_night_temporal.asset +++ b/data/assets/scene/solarsystem/planets/earth/layers/nightlayers/earth_at_night_temporal.asset @@ -1,18 +1,15 @@ local globe = asset.require("../../earth") - -local Layer = { - Identifier = "Earth_at_Night_Temporal", - Name = "Earth at Night (Temporal)", - Enabled = asset.enabled, - ZIndex = 20, +local NearConstantContrastLayer = { + Identifier = "VIIRS_SNPP_DayNightBand_ENCC", + Name = "Nighttime Imagery (Day/Night Band, Enhanced Near Constant Contrast)", Type = "TemporalTileProvider", Mode = "Prototyped", Prototyped = { Time = { - Start = "2012-05-08", - End = "Yesterday" + Start = "2016-11-30", + End = "2020-11-18" }, TemporalResolution = "1d", TimeFormat = "YYYY-MM-DD", @@ -42,6 +39,105 @@ local Layer = { temporal resolution is daily. (Description from NASA Worldview)]] } +local BlackMarbleRadianceSNPP = { + Identifier = "VIIRS_SNPP_DayNightBand_At_Sensor_Radiance", + Name = "Black Marble Nighttime At Sensor Radiance (Day/Night Band)", + Type = "TemporalTileProvider", + Mode = "Prototyped", + Prototyped = { + Time = { + Start = "2020-11-18", + End = "2024-03-25" + }, + TemporalResolution = "1d", + TimeFormat = "YYYY-MM-DD", + Prototype = openspace.globebrowsing.createTemporalGibsGdalXml( + "VIIRS_SNPP_DayNightBand_At_Sensor_Radiance", + "500m", + "png" + ) + }, + Description = [[The Black Marble Nighttime At Sensor Radiance (Day/Night Band) layer is + created from NASA's Black Marble daily at-sensor top-of-atmosphere nighttime radiance + product (VNP46A1). It is displayed as a grayscale image. The layer is expressed in + radiance units (nW/(cm2 sr)) with log10 conversion. It is stretched up to + 38 nW/(cm2 sr) resulting in improvements in capturing city lights in greater spatial + detail than traditional Nighttime Imagery resampled at 0-255 (e.g., Day/Night Band, + Enhanced Near Constant Contrast). + + The ultra-sensitivity of the VIIRS Day/Night Band enables scientists to capture the + Earth's surface and atmosphere in low light conditions, allowing for better monitoring + of nighttime phenomena. These images are also useful for assessing anthropogenic + sources of light emissions under varying illumination conditions. For instance, during + partial to full moon conditions, the layer can identify the location and features of + clouds and other natural terrestrial features such as sea ice and snow cover, while + enabling temporal observations in urban regions, regardless of moonlit conditions. As + such, the layer is particularly useful for detecting city lights, lightning, auroras, + fires, gas flares, and fishing fleets. + + The Black Marble Nighttime At Sensor Radiance (Day/Night Band) layer is available in + near real-time from the Visible Infrared Imaging Radiometer Suite (VIIRS) aboard the + joint NASA/NOAA Suomi National Polar orbiting Partnership (Suomi NPP) satellite. The + sensor resolution is 750 m at nadir, imagery resolution is 500 m, and the temporal + resolution is daily.)]] +} + +local BlackMarbleRadianceNOAA20 = { + Identifier = "VIIRS_NOAA20_DayNightBand_At_Sensor_Radiance", + Name = "Black Marble Nighttime At Sensor Radiance (Day/Night Band) ", + Type = "TemporalTileProvider", + Mode = "Prototyped", + Prototyped = { + Time = { + Start = "2024-03-25", + End = "Yesterday" + }, + TemporalResolution = "1d", + TimeFormat = "YYYY-MM-DD", + Prototype = openspace.globebrowsing.createTemporalGibsGdalXml( + "VIIRS_NOAA20_DayNightBand_At_Sensor_Radiance", + "500m", + "png" + ) + }, + Description = [[The Black Marble Nighttime At Sensor Radiance (Day/Night Band) layer is + created from NASA's Black Marble daily at-sensor top-of-atmosphere nighttime radiance + product (VJ146A1). It is displayed as a grayscale image. The layer is expressed in + radiance units (nW/(cm2 sr)) with log10 conversion. It is stretched up to + 38 nW/(cm2 sr) resulting in improvements in capturing city lights in greater spatial + detail than traditional Nighttime Imagery resampled at 0-255 (e.g., Day/Night Band, + Enhanced Near Constant Contrast). + + The ultra-sensitivity of the VIIRS Day/Night Band enables scientists to capture the + Earth's surface and atmosphere in low light conditions, allowing for better monitoring + of nighttime phenomena. These images are also useful for assessing anthropogenic + sources of light emissions under varying illumination conditions. For instance, during + partial to full moon conditions, the layer can identify the location and features of + clouds and other natural terrestrial features such as sea ice and snow cover, while + enabling temporal observations in urban regions, regardless of moonlit conditions. As + such, the layer is particularly useful for detecting city lights, lightning, auroras, + fires, gas flares, and fishing fleets. + + The Black Marble Nighttime At Sensor Radiance (Day/Night Band) layer is available in + near real-time from the Visible Infrared Imaging Radiometer Suite (VIIRS) aboard the + joint NASA/NOAA NOAA-20 (JPSS-1) satellite. The sensor resolution is 750 m at nadir, + imagery resolution is 500 m, and the temporal resolution is daily.]] +} + +local Layer = { + Identifier = "Earth_at_Night_Temporal", + Name = "Earth at Night (Temporal)", + Enabled = asset.enabled, + ZIndex = 20, + Type = "TileProviderByDate", + Providers = { + ["2016-11-30"] = NearConstantContrastLayer, + ["2020-11-18"] = BlackMarbleRadianceSNPP, + ["2024-03-25"] = BlackMarbleRadianceNOAA20 + }, + Description = [[This layer combines multiple other layers to provide a constant view + of Earth's nocturnal landscape. See the individual layers for more information.]] +} asset.onInitialize(function() openspace.globebrowsing.addLayer(globe.Earth.Identifier, "NightLayers", Layer) diff --git a/data/assets/scene/solarsystem/planets/earth/layers/nightlayers/earth_night_texture.asset b/data/assets/scene/solarsystem/planets/earth/layers/nightlayers/earth_night_texture.asset index 588f856b0d..59f6650129 100644 --- a/data/assets/scene/solarsystem/planets/earth/layers/nightlayers/earth_night_texture.asset +++ b/data/assets/scene/solarsystem/planets/earth/layers/nightlayers/earth_night_texture.asset @@ -16,8 +16,7 @@ local Layer = { Enabled = asset.enabled, ZIndex = 5, FilePath = texturesPath .. "earth_night.png", - Description = "Earth's city lights are clearly visible from space", - CacheSettings = { Enabled = false } + Description = "Earth's city lights are clearly visible from space" } diff --git a/data/assets/scene/solarsystem/planets/earth/moon/layers/colorlayers/moon_texture.asset b/data/assets/scene/solarsystem/planets/earth/moon/layers/colorlayers/moon_texture.asset index f2bfa53954..138c1acb30 100644 --- a/data/assets/scene/solarsystem/planets/earth/moon/layers/colorlayers/moon_texture.asset +++ b/data/assets/scene/solarsystem/planets/earth/moon/layers/colorlayers/moon_texture.asset @@ -16,8 +16,7 @@ local Layer = { Enabled = asset.enabled, ZIndex = 5, FilePath = texturesPath .. "WAC_GLOBAL_E000N0000_032P.png", - Description = "Lower Resolution offline version of WAC layer", - CacheSettings = { Enabled = false } + Description = "Lower Resolution offline version of WAC layer" } diff --git a/data/assets/scene/solarsystem/planets/earth/moon/markers.asset b/data/assets/scene/solarsystem/planets/earth/moon/markers.asset index 7516de40e7..d8445dc0f2 100644 --- a/data/assets/scene/solarsystem/planets/earth/moon/markers.asset +++ b/data/assets/scene/solarsystem/planets/earth/moon/markers.asset @@ -24,7 +24,8 @@ local MoonMarker = { }, GUI = { Name = "Moon Marker", - Path = "/Solar System/Planets/Earth/Moon" + Path = "/Solar System/Planets/Earth/Moon", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/moon/moon.asset b/data/assets/scene/solarsystem/planets/earth/moon/moon.asset index ec6b2f0c33..225053fbf7 100644 --- a/data/assets/scene/solarsystem/planets/earth/moon/moon.asset +++ b/data/assets/scene/solarsystem/planets/earth/moon/moon.asset @@ -52,6 +52,7 @@ local Moon = { Color = { 1.0, 1.0, 0.0 } } }, + Tag = { "moon_solarSystem", "moon_terrestrial", "moon_earth" }, GUI = { Path = "/Solar System/Planets/Earth/Moon" } @@ -78,6 +79,7 @@ local MoonLabel = { GUI = { Name = "Moon Label", Path = "/Solar System/Planets/Earth/Moon", + Focusable = false, Description = "Label for Earth's Moon" } } diff --git a/data/assets/scene/solarsystem/planets/earth/moon/trail.asset b/data/assets/scene/solarsystem/planets/earth/moon/trail.asset index a167a23b96..870cfd5a12 100644 --- a/data/assets/scene/solarsystem/planets/earth/moon/trail.asset +++ b/data/assets/scene/solarsystem/planets/earth/moon/trail.asset @@ -15,12 +15,17 @@ local MoonTrail = { }, Color = { 0.5, 0.3, 0.3 }, Period = 27, - Resolution = 1000, - Tag = { "moonTrail_solarSystem", "moonTrail_terrestrial", "moonTrail_earth" } + Resolution = 1000 + }, + Tag = { + "moonTrail_solarSystem", + "moonTrail_terrestrial", + "moonTrail_earth" }, GUI = { Name = "Moon Trail", - Path = "/Solar System/Planets/Earth/Moon" + Path = "/Solar System/Planets/Earth/Moon", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/noaa-sos/land/blue_marble-blue_marble.asset b/data/assets/scene/solarsystem/planets/earth/noaa-sos/land/blue_marble-blue_marble.asset index e7a4b7c439..6cebb50492 100644 --- a/data/assets/scene/solarsystem/planets/earth/noaa-sos/land/blue_marble-blue_marble.asset +++ b/data/assets/scene/solarsystem/planets/earth/noaa-sos/land/blue_marble-blue_marble.asset @@ -31,8 +31,7 @@ local Layer = { Enabled = asset.enabled, ZIndex = 100, FilePath = syncedDirectory .. "4096.jpg", - Description = Description, - CacheSettings = { Enabled = false } + Description = Description } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/communications/amateur.asset b/data/assets/scene/solarsystem/planets/earth/satellites/communications/amateur.asset index ed48d2e0a3..b46ed23b85 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/communications/amateur.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/communications/amateur.asset @@ -28,7 +28,8 @@ local AmateurSatellites = { Tag = { "earth_satellites" }, GUI = { Name = "Amateur Radio", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/communications/experimental.asset b/data/assets/scene/solarsystem/planets/earth/satellites/communications/experimental.asset index fc9655828f..2696e21905 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/communications/experimental.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/communications/experimental.asset @@ -28,7 +28,8 @@ local ExperimentalSatellites = { Tag = { "earth_satellites" }, GUI = { Name = "Experimental", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/communications/geostationary.asset b/data/assets/scene/solarsystem/planets/earth/satellites/communications/geostationary.asset index c8ff854b88..67e814edc4 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/communications/geostationary.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/communications/geostationary.asset @@ -29,6 +29,7 @@ local GeoStationarySatellites = { GUI = { Name = "Geostationary", Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false, Description = [[Satellites that are currently active and in a Geosynchronous orbit, meaning their orbital period matches Earth's rotation.]] } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/communications/globalstar.asset b/data/assets/scene/solarsystem/planets/earth/satellites/communications/globalstar.asset index a76d042f90..3ea3ade5a0 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/communications/globalstar.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/communications/globalstar.asset @@ -28,7 +28,8 @@ local GlobalStarSatellites = { Tag = { "earth_satellites" }, GUI = { Name = "GlobalStar", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/communications/gorizont.asset b/data/assets/scene/solarsystem/planets/earth/satellites/communications/gorizont.asset index bb74c08ce4..0b3858db90 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/communications/gorizont.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/communications/gorizont.asset @@ -28,7 +28,8 @@ local GorizontSatellites = { Tag = { "earth_satellites" }, GUI = { Name = "Gorizont", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/communications/intelsat.asset b/data/assets/scene/solarsystem/planets/earth/satellites/communications/intelsat.asset index 4601e65efe..74246f3bd5 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/communications/intelsat.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/communications/intelsat.asset @@ -28,7 +28,8 @@ local IntelsatSatellites = { Tag = { "earth_satellites" }, GUI = { Name = "Intelsat", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/communications/iridium.asset b/data/assets/scene/solarsystem/planets/earth/satellites/communications/iridium.asset index 12c4a6e28e..9588ffbd7b 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/communications/iridium.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/communications/iridium.asset @@ -28,7 +28,8 @@ local IridiumSatellites = { Tag = { "earth_satellites" }, GUI = { Name = "Iridium", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/communications/iridium_next.asset b/data/assets/scene/solarsystem/planets/earth/satellites/communications/iridium_next.asset index 759e31cafd..1d632a70d9 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/communications/iridium_next.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/communications/iridium_next.asset @@ -28,7 +28,8 @@ local IridiumNextSatellites = { Tag = { "earth_satellites" }, GUI = { Name = "Iridium NEXT", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/communications/kuiper.asset b/data/assets/scene/solarsystem/planets/earth/satellites/communications/kuiper.asset new file mode 100644 index 0000000000..2bb88d5847 --- /dev/null +++ b/data/assets/scene/solarsystem/planets/earth/satellites/communications/kuiper.asset @@ -0,0 +1,57 @@ +local transforms = asset.require("scene/solarsystem/planets/earth/transforms") + + + +local omm = asset.resource({ + Name = "Satellite OMM Data (Kuiper)", + Type = "UrlSynchronization", + Identifier = "satellite_omm_data_kuiper", + Url = "https://celestrak.org/NORAD/elements/supplemental/sup-gp.php?FILE=kuiper&FORMAT=kvn", + Filename = "kuiper.txt", + SecondsUntilResync = openspace.time.secondsPerDay() +}) + + +local KuiperSatellites = { + Identifier = "KuiperSatellites", + Parent = transforms.EarthInertial.Identifier, + Renderable = { + Type = "RenderableOrbitalKepler", + Path = omm .. "kuiper.txt", + Format = "OMM", + SegmentQuality = 3, + Color = { 0.95, 0.82, 0.25 }, + TrailFade = 5, + PointSizeExponent = 5.0, + RenderBinMode = "PostDeferredTransparent" + }, + Tag = { "earth_satellites" }, + GUI = { + Name = "Kuiper", + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false, + Description = [[LEO satellite constellation launched by Amazon to provide broadband + internet access.]] + } +} + + +asset.onInitialize(function() + openspace.addSceneGraphNode(KuiperSatellites) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(KuiperSatellites) +end) + +asset.export(KuiperSatellites) + + + +asset.meta = { + Name = "Satellites Communications - Kuiper", + Description = "Satellites asset for Communications - Kuipter. Data from Celestrak", + Author = "OpenSpace Team", + URL = "https://celestrak.com/NORAD/elements/", + License = "Celestrak" +} diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/communications/molniya.asset b/data/assets/scene/solarsystem/planets/earth/satellites/communications/molniya.asset index 58586625e0..5f15a1695e 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/communications/molniya.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/communications/molniya.asset @@ -28,7 +28,8 @@ local MolniyaSatellites = { Tag = { "earth_satellites" }, GUI = { Name = "Molniya", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/communications/orbcomm.asset b/data/assets/scene/solarsystem/planets/earth/satellites/communications/orbcomm.asset index 107171335d..bd0fc73554 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/communications/orbcomm.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/communications/orbcomm.asset @@ -28,7 +28,8 @@ local OrbcommSatellites = { Tag = { "earth_satellites" }, GUI = { Name = "Orbcomm", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/communications/other_comm.asset b/data/assets/scene/solarsystem/planets/earth/satellites/communications/other_comm.asset index ab09abef8a..b3ad87f9e8 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/communications/other_comm.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/communications/other_comm.asset @@ -28,7 +28,8 @@ local OtherCommunicationSatellites = { Tag = { "earth_satellites" }, GUI = { Name = "Other comm", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/communications/raduga.asset b/data/assets/scene/solarsystem/planets/earth/satellites/communications/raduga.asset index ba24bec98c..645d481fac 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/communications/raduga.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/communications/raduga.asset @@ -28,7 +28,8 @@ local RadugaSatellites = { Tag = { "earth_satellites" }, GUI = { Name = "Raduga", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/communications/ses.asset b/data/assets/scene/solarsystem/planets/earth/satellites/communications/ses.asset index 8a2ae6cfe1..a0cce6703a 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/communications/ses.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/communications/ses.asset @@ -28,7 +28,8 @@ local SesSatellites = { Tag = { "earth_satellites" }, GUI = { Name = "SES", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/communications/starlink.asset b/data/assets/scene/solarsystem/planets/earth/satellites/communications/starlink.asset index 323cdd446b..0797b0b5eb 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/communications/starlink.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/communications/starlink.asset @@ -29,6 +29,7 @@ local StarlinkSatellites = { GUI = { Name = "Starlink", Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false, Description = [[LEO satellite constellation launched by SpaceX to provide broadband internet access.]] } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/debris/debris_breezem.asset b/data/assets/scene/solarsystem/planets/earth/satellites/debris/debris_breezem.asset index 085e280b89..6325970fc4 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/debris/debris_breezem.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/debris/debris_breezem.asset @@ -28,7 +28,8 @@ local DebrisBreezem = { Tag = { "earth_satellites" }, GUI = { Name = "Breeze-M Breakup", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/debris/debris_fengyun.asset b/data/assets/scene/solarsystem/planets/earth/satellites/debris/debris_fengyun.asset index a52a8393ff..6b082194a9 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/debris/debris_fengyun.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/debris/debris_fengyun.asset @@ -28,7 +28,8 @@ local DebrisFengyun = { Tag = { "earth_satellites" }, GUI = { Name = "Fengyun Debris", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/debris/debris_iridium33.asset b/data/assets/scene/solarsystem/planets/earth/satellites/debris/debris_iridium33.asset index bc251261fe..3cbefd817d 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/debris/debris_iridium33.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/debris/debris_iridium33.asset @@ -28,7 +28,8 @@ local DebrisIridium = { Tag = { "earth_satellites" }, GUI = { Name = "Iridium 33 Debris", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/debris/debris_kosmos2251.asset b/data/assets/scene/solarsystem/planets/earth/satellites/debris/debris_kosmos2251.asset index bcad916d9f..71949a168f 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/debris/debris_kosmos2251.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/debris/debris_kosmos2251.asset @@ -22,12 +22,14 @@ local DebrisCosmos = { SegmentQuality = 3, Color = { 0.66, 0.8, 0.5 }, TrailFade = 1.5, + PointSizeExponent = 5.0, RenderBinMode = "PostDeferredTransparent" }, Tag = { "earth_satellites" }, GUI = { Name = "Kosmos 2251 Debris", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/misc/active.asset b/data/assets/scene/solarsystem/planets/earth/satellites/misc/active.asset index e13d13d328..f24b1331bf 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/misc/active.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/misc/active.asset @@ -29,6 +29,7 @@ local ActiveSatellites = { GUI = { Name = "Active", Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false, Description = [[Satellites that employ active communication.]] } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/misc/brightest.asset b/data/assets/scene/solarsystem/planets/earth/satellites/misc/brightest.asset index c02b1d4735..31941a1481 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/misc/brightest.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/misc/brightest.asset @@ -29,6 +29,7 @@ local BrightestSatellites = { GUI = { Name = "100 Brightest", Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false, Description = [[The 100 (or so) satellites that will appear brightest when viewed from Earth.]] } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/misc/cubesats.asset b/data/assets/scene/solarsystem/planets/earth/satellites/misc/cubesats.asset index 7188ae6c79..5c769c5cf2 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/misc/cubesats.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/misc/cubesats.asset @@ -28,7 +28,8 @@ local Cubesats = { Tag = { "earth_satellites" }, GUI = { Name = "CubeSat", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/misc/hubble_trail.asset b/data/assets/scene/solarsystem/planets/earth/satellites/misc/hubble_trail.asset index b29818479d..9849267e6f 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/misc/hubble_trail.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/misc/hubble_trail.asset @@ -29,10 +29,11 @@ local HubblePosition = { DestinationFrame = coreKernels.Frame.J2000 } }, - Tag = { "earth_satellite", "hubble" }, + Tag = { "earth_satellites", "hubble" }, GUI = { Name = "Hubble Position", Path = "/Solar System/Planets/Earth/Satellites/Hubble", + Focusable = false, Hidden = true } } @@ -53,10 +54,11 @@ local HubbleTrail = { Fade = 1.5, Resolution = 320 }, - Tag = { "earth_satellite", "hubble" }, + Tag = { "earth_satellites", "hubble" }, GUI = { Name = "Hubble Trail", - Path = "/Solar System/Planets/Earth/Satellites/Hubble" + Path = "/Solar System/Planets/Earth/Satellites/Hubble", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/misc/iss.asset b/data/assets/scene/solarsystem/planets/earth/satellites/misc/iss.asset index 36efd6a593..abb3ee01e5 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/misc/iss.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/misc/iss.asset @@ -49,7 +49,7 @@ local IssPosition = { Format = "OMM" } }, - Tag = { "earth_satellite", "ISS" }, + Tag = { "earth_satellites", "ISS", "space_stations" }, GUI = { Name = "ISS Position", Path = "/Solar System/Planets/Earth/Satellites/ISS", @@ -76,7 +76,7 @@ local IssModel = { }, PerformShading = true }, - Tag = { "earth_satellite", "ISS" }, + Tag = { "earth_satellites", "ISS", "space_stations" }, GUI = { Name = "ISS", Path = "/Solar System/Planets/Earth/Satellites/ISS" @@ -99,10 +99,11 @@ local IssTrail = { Fade = 1.5, Resolution = 320 }, - Tag = { "earth_satellite", "ISS" }, + Tag = { "earth_satellites", "ISS", "space_stations", "trails" }, GUI = { Name = "ISS Trail", - Path = "/Solar System/Planets/Earth/Satellites/ISS" + Path = "/Solar System/Planets/Earth/Satellites/ISS", + Focusable = false } } @@ -123,10 +124,11 @@ local IssLabel = { FadeDistances = { 0.15, 15.0 }, FadeWidths = { 1.0, 25.0 } }, - Tag = { "solarsystem_labels" }, + Tag = { "solarsystem_labels", "earth_satellites", "ISS", "space_stations", "labels" }, GUI = { Name = "ISS Label", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/misc/military.asset b/data/assets/scene/solarsystem/planets/earth/satellites/misc/military.asset index 1098be5793..1a5bade094 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/misc/military.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/misc/military.asset @@ -28,7 +28,8 @@ local MilitarySatellites = { Tag = { "earth_satellites" }, GUI = { Name = "Military", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/misc/other.asset b/data/assets/scene/solarsystem/planets/earth/satellites/misc/other.asset index 64ea9f90d9..2521eaf549 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/misc/other.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/misc/other.asset @@ -28,7 +28,8 @@ local OtherSatellites = { Tag = { "earth_satellites" }, GUI = { Name = "Other", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/misc/radar.asset b/data/assets/scene/solarsystem/planets/earth/satellites/misc/radar.asset index 75d2402b85..ef0cbd1306 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/misc/radar.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/misc/radar.asset @@ -28,7 +28,8 @@ local RadarSatellites = { Tag = { "earth_satellites" }, GUI = { Name = "Radar Calibration", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/misc/spacestations.asset b/data/assets/scene/solarsystem/planets/earth/satellites/misc/spacestations.asset index ad7ef07723..63c5cd5a7a 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/misc/spacestations.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/misc/spacestations.asset @@ -29,6 +29,7 @@ local SpaceStations = { GUI = { Name = "Space Stations", Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false, Description = [[A collection of space stations (including the ISS and China's Tiangong), along with certain cubesats and satellite constellations from space agencies.]] diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/misc/tiangong.asset b/data/assets/scene/solarsystem/planets/earth/satellites/misc/tiangong.asset index 5f421a2df9..4cc73cf686 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/misc/tiangong.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/misc/tiangong.asset @@ -37,10 +37,11 @@ local TiangongPosition = { DestinationFrame = coreKernels.Frame.J2000 } }, - Tag = { "earth_satellite" }, + Tag = { "earth_satellites", "Tiangong", "space_stations" }, GUI = { Name = "Tiangong Position", Path = "/Solar System/Planets/Earth/Satellites/Tiangong", + Focusable = false, Hidden = true } } @@ -65,7 +66,7 @@ local TiangongModel = { }, PerformShading = true }, - Tag = { "earth_satellite" }, + Tag = { "earth_satellites", "Tiangong", "space_stations" }, GUI = { Name = "Tiangong", Path = "/Solar System/Planets/Earth/Satellites/Tiangong" @@ -88,10 +89,11 @@ local TiangongTrail = { Fade = 1.5, Resolution = 320 }, - Tag = { "earth_satellite" }, + Tag = { "earth_satellites", "Tiangong", "space_stations", "trails" }, GUI = { Name = "Tiangong Trail", - Path = "/Solar System/Planets/Earth/Satellites/Tiangong" + Path = "/Solar System/Planets/Earth/Satellites/Tiangong", + Focusable = false } } @@ -112,10 +114,17 @@ local TiangongLabel = { FadeDistances = { 0.15, 15.0 }, FadeWidths = { 1.0, 25.0 } }, - Tag = { "solarsystem_labels" }, + Tag = { + "solarsystem_labels", + "earth_satellites", + "Tiangong", + "space_stations", + "labels" + }, GUI = { Name = "Tiangong Label", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/misc/tle-new.asset b/data/assets/scene/solarsystem/planets/earth/satellites/misc/tle-new.asset index cd7537f716..8e34e99bfc 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/misc/tle-new.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/misc/tle-new.asset @@ -29,6 +29,7 @@ local Last30DaysSatellites = { GUI = { Name = "Last 30 Days", Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false, Description = [[All the satellites that have been launched in the last 30 days.]] } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/navigation/beidou.asset b/data/assets/scene/solarsystem/planets/earth/satellites/navigation/beidou.asset index dfd9306d03..8770680ded 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/navigation/beidou.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/navigation/beidou.asset @@ -28,7 +28,8 @@ local BeidouSatellites = { Tag = { "earth_satellites" }, GUI = { Name = "Beidou", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/navigation/galileo.asset b/data/assets/scene/solarsystem/planets/earth/satellites/navigation/galileo.asset index 4a905b2cdd..a13e237a8c 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/navigation/galileo.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/navigation/galileo.asset @@ -28,7 +28,8 @@ local GalileoSatellites = { Tag = { "earth_satellites" }, GUI = { Name = "Galileo", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/navigation/glosnass.asset b/data/assets/scene/solarsystem/planets/earth/satellites/navigation/glosnass.asset index 84b6de8b2f..06b3e20dd6 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/navigation/glosnass.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/navigation/glosnass.asset @@ -28,7 +28,8 @@ local GlosnassSatellites = { Tag = { "earth_satellites" }, GUI = { Name = "Glosnass", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/navigation/gps.asset b/data/assets/scene/solarsystem/planets/earth/satellites/navigation/gps.asset index 31b8578fb6..796dd46f0c 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/navigation/gps.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/navigation/gps.asset @@ -29,6 +29,7 @@ local GpsSatellites = { GUI = { Name = "GPS", Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false, Description = [[The GPS satellites that give us our precise locations back on Earth.]] } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/navigation/musson.asset b/data/assets/scene/solarsystem/planets/earth/satellites/navigation/musson.asset index 6b688a3585..1123530e2e 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/navigation/musson.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/navigation/musson.asset @@ -28,7 +28,8 @@ local MussonSatellites = { Tag = { "earth_satellites" }, GUI = { Name = "Russian LEO Navigation", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/navigation/nnss.asset b/data/assets/scene/solarsystem/planets/earth/satellites/navigation/nnss.asset index 0457dafb50..a18fbb2aef 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/navigation/nnss.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/navigation/nnss.asset @@ -29,6 +29,7 @@ local NavyNavigationSatellites = { GUI = { Name = "Navy Navigation Satellite System", Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false, Description = [[The first satellite navigation system to be used operationally.]] } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/navigation/sbas.asset b/data/assets/scene/solarsystem/planets/earth/satellites/navigation/sbas.asset index a092adf1d6..c2d1883ec3 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/navigation/sbas.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/navigation/sbas.asset @@ -28,7 +28,8 @@ local SatelliteBasedAugmentationSatellites = { Tag = { "earth_satellites" }, GUI = { Name = "Satellite Based Augmentation System", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/science/education.asset b/data/assets/scene/solarsystem/planets/earth/satellites/science/education.asset index d7567078de..7d7cd0165b 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/science/education.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/science/education.asset @@ -28,7 +28,8 @@ local EducationSatellites = { Tag = { "earth_satellites" }, GUI = { Name = "Education", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/science/engineering.asset b/data/assets/scene/solarsystem/planets/earth/satellites/science/engineering.asset index 5ee3c70cf3..65d74ea8aa 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/science/engineering.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/science/engineering.asset @@ -28,7 +28,8 @@ local EngineeringSatellites = { Tag = { "earth_satellites" }, GUI = { Name = "Engineering", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/science/geodetic.asset b/data/assets/scene/solarsystem/planets/earth/satellites/science/geodetic.asset index 656c7d6330..a8dcb6d935 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/science/geodetic.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/science/geodetic.asset @@ -28,7 +28,8 @@ local GeodeticSatellites = { Tag = { "earth_satellites" }, GUI = { Name = "Geodetic", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/science/spaceearth.asset b/data/assets/scene/solarsystem/planets/earth/satellites/science/spaceearth.asset index 8daedff803..89fa152d9e 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/science/spaceearth.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/science/spaceearth.asset @@ -28,7 +28,8 @@ local ScienceSatellites = { Tag = { "earth_satellites" }, GUI = { Name = "Space & Earth Science", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/weather/aqua.asset b/data/assets/scene/solarsystem/planets/earth/satellites/weather/aqua.asset index d8a9f8e2f3..f5c0123979 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/weather/aqua.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/weather/aqua.asset @@ -30,7 +30,7 @@ local Aqua = { DestinationFrame = coreKernels.Frame.J2000 } }, - Tag = { "earth_satellite", "Aqua" }, + Tag = { "earth_satellites", "Aqua" }, GUI = { Name = "Aqua", Path = "/Solar System/Planets/Earth/Satellites/Aqua" @@ -53,10 +53,11 @@ local AquaTrail = { Fade = 1.5, Resolution = 320 }, - Tag = { "earth_satellite", "Aqua" }, + Tag = { "earth_satellites", "Aqua" }, GUI = { Name = "Aqua Trail", - Path = "/Solar System/Planets/Earth/Satellites/Aqua" + Path = "/Solar System/Planets/Earth/Satellites/Aqua", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/weather/argos.asset b/data/assets/scene/solarsystem/planets/earth/satellites/weather/argos.asset index fd2a4bab75..6f5871d6ac 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/weather/argos.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/weather/argos.asset @@ -28,7 +28,8 @@ local Argos = { Tag = { "earth_satellites" }, GUI = { Name = "ARGOS", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/weather/dmc.asset b/data/assets/scene/solarsystem/planets/earth/satellites/weather/dmc.asset index 051a79b8c1..f7810d2894 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/weather/dmc.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/weather/dmc.asset @@ -28,7 +28,8 @@ local DisasterMonitoringConstellation = { Tag = { "earth_satellites" }, GUI = { Name = "Disaster Monitoring", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/weather/earth_resources.asset b/data/assets/scene/solarsystem/planets/earth/satellites/weather/earth_resources.asset index 5d23acbdb8..22de3bad19 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/weather/earth_resources.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/weather/earth_resources.asset @@ -28,7 +28,8 @@ local ResourceSatellites = { Tag = { "earth_satellites" }, GUI = { Name = "Earth Resources", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/weather/goes.asset b/data/assets/scene/solarsystem/planets/earth/satellites/weather/goes.asset index 68d2a9dd4e..b43d3205ae 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/weather/goes.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/weather/goes.asset @@ -28,7 +28,8 @@ local GoesSatellites = { Tag = { "earth_satellites" }, GUI = { Name = "GOES", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/weather/noaa.asset b/data/assets/scene/solarsystem/planets/earth/satellites/weather/noaa.asset index d3e360be01..77227dcbeb 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/weather/noaa.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/weather/noaa.asset @@ -28,7 +28,8 @@ local NoaaSatellites = { Tag = { "earth_satellites" }, GUI = { Name = "NOAA", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/weather/planet.asset b/data/assets/scene/solarsystem/planets/earth/satellites/weather/planet.asset index c9148ea6a7..99dfc5fa0d 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/weather/planet.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/weather/planet.asset @@ -28,7 +28,8 @@ local PlanetSatellites = { Tag = { "earth_satellites" }, GUI = { Name = "Planet", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/weather/sarsat.asset b/data/assets/scene/solarsystem/planets/earth/satellites/weather/sarsat.asset index a786fa426c..e7fa6f5132 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/weather/sarsat.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/weather/sarsat.asset @@ -28,7 +28,8 @@ local SarSatellites = { Tag = { "earth_satellites" }, GUI = { Name = "Search & Rescue (SARSAT)", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/weather/snpp.asset b/data/assets/scene/solarsystem/planets/earth/satellites/weather/snpp.asset index 3094da65ec..b3bac7fb97 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/weather/snpp.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/weather/snpp.asset @@ -30,7 +30,7 @@ local SNPP = { DestinationFrame = coreKernels.Frame.J2000 } }, - Tag = { "earth_satellite", "SNPP" }, + Tag = { "earth_satellites", "SNPP" }, GUI = { Name = "SNPP", Path = "/Solar System/Planets/Earth/Satellites/SNPP" @@ -53,10 +53,11 @@ local SNPPTrail = { Fade = 1.5, Resolution = 320 }, - Tag = { "earth_satellite", "SNPP" }, + Tag = { "earth_satellites", "SNPP" }, GUI = { Name = "SNPP Trail", - Path = "/Solar System/Planets/Earth/Satellites/SNPP" + Path = "/Solar System/Planets/Earth/Satellites/SNPP", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/weather/spire.asset b/data/assets/scene/solarsystem/planets/earth/satellites/weather/spire.asset index 972274778a..38174babb3 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/weather/spire.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/weather/spire.asset @@ -28,7 +28,8 @@ local SpireSatellites = { Tag = { "earth_satellites" }, GUI = { Name = "Spire", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/weather/tdrss.asset b/data/assets/scene/solarsystem/planets/earth/satellites/weather/tdrss.asset index e44459833c..d1f8a5cee4 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/weather/tdrss.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/weather/tdrss.asset @@ -28,7 +28,8 @@ local TrackingDataRelaySatellites = { Tag = { "earth_satellites" }, GUI = { Name = "Tracking and Data Relay Satellite System (TDRSS)", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/weather/terra.asset b/data/assets/scene/solarsystem/planets/earth/satellites/weather/terra.asset index ba5fbdb877..4e6e7c860b 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/weather/terra.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/weather/terra.asset @@ -30,7 +30,7 @@ local Terra = { DestinationFrame = coreKernels.Frame.J2000 } }, - Tag = { "earth_satellite", "Terra" }, + Tag = { "earth_satellites", "Terra" }, GUI = { Name = "Terra", Path = "/Solar System/Planets/Earth/Satellites/Terra" @@ -53,10 +53,11 @@ local TerraTrail = { Fade = 1.5, Resolution = 320 }, - Tag = { "earth_satellite", "Terra" }, + Tag = { "earth_satellites", "Terra" }, GUI = { Name = "Terra Trail", - Path = "/Solar System/Planets/Earth/Satellites/Terra" + Path = "/Solar System/Planets/Earth/Satellites/Terra", + Focusable = false } } @@ -82,7 +83,8 @@ local TerraLabel = { Tag = { "solarsystem_labels" }, GUI = { Name = "Terra Label", - Path = "/Solar System/Planets/Earth" + Path = "/Solar System/Planets/Earth/Satellites/Terra", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/weather/weather.asset b/data/assets/scene/solarsystem/planets/earth/satellites/weather/weather.asset index c4a0c29460..bddba2caa1 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/weather/weather.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/weather/weather.asset @@ -28,7 +28,8 @@ local WeatherSatellites = { Tag = { "earth_satellites" }, GUI = { Name = "Weather", - Path = "/Solar System/Planets/Earth/Satellites" + Path = "/Solar System/Planets/Earth/Satellites", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/trail.asset b/data/assets/scene/solarsystem/planets/earth/trail.asset index a127de8615..ef2ad50807 100644 --- a/data/assets/scene/solarsystem/planets/earth/trail.asset +++ b/data/assets/scene/solarsystem/planets/earth/trail.asset @@ -20,7 +20,8 @@ local EarthTrail = { Tag = { "planetTrail_solarSystem", "planetTrail_terrestrial" }, GUI = { Name = "Earth Trail", - Path = "/Solar System/Planets/Earth" + Path = "/Solar System/Planets/Earth", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/trail_barycenter.asset b/data/assets/scene/solarsystem/planets/earth/trail_barycenter.asset index 5687a9ff23..630b197406 100644 --- a/data/assets/scene/solarsystem/planets/earth/trail_barycenter.asset +++ b/data/assets/scene/solarsystem/planets/earth/trail_barycenter.asset @@ -21,7 +21,8 @@ local EarthBarycenterTrail = { Tag = { "planetTrail_solarSystem", "planetTrail_terrestrial" }, GUI = { Name = "Earth Barycenter Trail", - Path = "/Solar System/Planets/Earth" + Path = "/Solar System/Planets/Earth", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/earth/transforms.asset b/data/assets/scene/solarsystem/planets/earth/transforms.asset index d3bbfae3da..84f66fc2c0 100644 --- a/data/assets/scene/solarsystem/planets/earth/transforms.asset +++ b/data/assets/scene/solarsystem/planets/earth/transforms.asset @@ -16,6 +16,7 @@ local EarthBarycenter = { GUI = { Name = "Earth Barycenter", Path = "/Solar System/Planets/Earth", + Focusable = false, Hidden = true } } @@ -33,6 +34,7 @@ local EarthCenter = { GUI = { Name = "Earth Center", Path = "/Solar System/Planets/Earth", + Focusable = false, Hidden = true } } @@ -51,6 +53,7 @@ local EarthInertial = { GUI = { Name = "Earth Inertial", Path = "/Solar System/Planets/Earth", + Focusable = false, Hidden = true } } @@ -68,6 +71,7 @@ local EarthIAU = { GUI = { Name = "Earth IAU", Path = "/Solar System/Planets/Earth", + Focusable = false, Hidden = true } } diff --git a/data/assets/scene/solarsystem/planets/earth/transforms_gse.asset b/data/assets/scene/solarsystem/planets/earth/transforms_gse.asset index 84e5d71b57..522274a417 100644 --- a/data/assets/scene/solarsystem/planets/earth/transforms_gse.asset +++ b/data/assets/scene/solarsystem/planets/earth/transforms_gse.asset @@ -27,13 +27,13 @@ local GeocentricSolarEcliptic = { GUI = { Name = "Geocentric Solar Ecliptic", Path = "/Solar System/Planets/Earth", + Focusable = false, + Hidden = true, Description = [[The X-Y plane is defined by the Earth Mean Ecliptic plane of date: - the +Z axis, primary vector, is the normal vector to this plane, - always pointing toward the North side of the invariant plane. - +X axis is the component of the Earth-Sun vector that is orthogonal - to the +Z axis. - +Y axis completes the right-handed system.]], - Hidden = true + the +Z axis, primary vector, is the normal vector to this plane, always pointing + toward the North side of the invariant plane. +X axis is the component of the + Earth-Sun vector that is orthogonal to the +Z axis. +Y axis completes the + right-handed system.]] } } diff --git a/data/assets/scene/solarsystem/planets/earth/transforms_gsm_sm.asset b/data/assets/scene/solarsystem/planets/earth/transforms_gsm_sm.asset index 6b3bf4d13b..2823d218e0 100644 --- a/data/assets/scene/solarsystem/planets/earth/transforms_gsm_sm.asset +++ b/data/assets/scene/solarsystem/planets/earth/transforms_gsm_sm.asset @@ -28,12 +28,12 @@ local GeocentricSolarMagnetospheric = { GUI = { Name = "Geocentric Solar Magnetospheric", Path = "/Solar System/Planets/Earth", - Description = [[ +X is parallel to the geometric earth-sun position vector. - +Z axis is normalized component of north centered geomagnetic dipole - vector orthogonal to GSM +X axis. - +Y completes the right-handed frame. - - the origin of this frame is the center of mass of the Earth.]], - Hidden = true + Focusable = false, + Hidden = true, + Description = [[+X is parallel to the geometric earth-sun position vector. +Z axis is + normalized component of north centered geomagnetic dipole vector orthogonal to GSM + +X axis. +Y completes the right-handed frame. The origin of this frame is the center + of mass of the Earth.]] } } @@ -50,14 +50,13 @@ local SolarMagnetic = { GUI = { Name = "Solar Magnetic", Path = "/Solar System/Planets/Earth", - Description = [[+Z axis is the direction of Earth's magnetic dipole axis - (positive North); it's the primary vector. - +X axis is the projection of the geometric position of the - Sun relative to the Earth onto the plane perpendicular to the - Z axis. - +Y axis completes the right-handed system. - - the origin of this frame is the center of mass of the Earth.]], - Hidden = true + Focusable = false, + Hidden = true, + Description = [[+Z axis is the direction of Earth's magnetic dipole axis (positive + North); it's the primary vector. +X axis is the projection of the geometric position + of the Sun relative to the Earth onto the plane perpendicular to the Z axis. +Y axis + completes the right-handed system. The origin of this frame is the center of mass + of the Earth.]] } } @@ -65,6 +64,7 @@ local SolarMagnetic = { asset.onInitialize(function() openspace.spice.loadKernel(earthcentricKernels .. "GSM.tf") openspace.spice.loadKernel(earthcentricKernels .. "SM.tf") + openspace.addSceneGraphNode(GeocentricSolarMagnetospheric) openspace.addSceneGraphNode(SolarMagnetic) end) @@ -72,6 +72,7 @@ end) asset.onDeinitialize(function() openspace.removeSceneGraphNode(SolarMagnetic) openspace.removeSceneGraphNode(GeocentricSolarMagnetospheric) + openspace.spice.unloadKernel(earthcentricKernels .. "SM.tf") openspace.spice.unloadKernel(earthcentricKernels .. "GSM.tf") end) diff --git a/data/assets/scene/solarsystem/planets/earth/transforms_gsm_sm_timedependent.asset b/data/assets/scene/solarsystem/planets/earth/transforms_gsm_sm_timedependent.asset index eaf1122589..d9c8194a5a 100644 --- a/data/assets/scene/solarsystem/planets/earth/transforms_gsm_sm_timedependent.asset +++ b/data/assets/scene/solarsystem/planets/earth/transforms_gsm_sm_timedependent.asset @@ -42,16 +42,15 @@ local GeocentricSolarMagnetosphericTimeDependent = { GUI = { Name = "Geocentric Solar Magnetospheric (Timedependent)", Path = "/Solar System/Planets/Earth", - Description = [[The Earth's magnetic dipole axis direction is time- - variable and is defined by the EARTH_NORTH_POLE/399901 object location - as seen from the Earth center provided in the SPK file - earthnpole_19500101_20251231_v01.bsp (or newer). - +X is parallel to the geometric earth-sun position vector. - +Z axis is normalized component of north centered geomagnetic dipole - vector orthogonal to GSM +X axis. - +Y completes the right-handed frame. - - the origin of this frame is the center of mass of the Earth.]], - Hidden = true + Focusable = false, + Hidden = true, + Description = [[The Earth's magnetic dipole axis direction is time-variable and is + defined by the EARTH_NORTH_POLE/399901 object location as seen from the Earth center + provided in the SPK file earthnpole_19500101_20251231_v01.bsp (or newer). +X is + parallel to the geometric earth-sun position vector. +Z axis is normalized component + of north centered geomagnetic dipole vector orthogonal to GSM +X axis. +Y completes + the right-handed frame. The origin of this frame is the center of mass of the + Earth.]] } } @@ -70,18 +69,15 @@ local SolarMagneticTimeDependent = { GUI = { Name = "Solar Magnetic (Timedependent)", Path = "/Solar System/Planets/Earth", - Description = [[ The Earth's magnetic dipole axis direction is time- - variable and is defined by the EARTH_NORTH_POLE/399901 object location - as seen from the Earth center provided in the SPK file - earthnpole_19500101_20251231_v01.bsp (or newer). - +Z axis is the direction of Earth's magnetic dipole axis - (positive North); it's the primary vector. - +X axis is the projection of the geometric position of the - Sun relative to the Earth onto the plane perpendicular to the - Z axis. - +Y axis completes the right-handed system. - - the origin of this frame is the center of mass of the Earth.]], - Hidden = true + Focusable = false, + Hidden = true, + Description = [[The Earth's magnetic dipole axis direction is time-variable and is + defined by the EARTH_NORTH_POLE/399901 object location as seen from the Earth center + provided in the SPK file earthnpole_19500101_20251231_v01.bsp (or newer). +Z axis is + the direction of Earth's magnetic dipole axis (positive North); it's the primary + vector. +X axis is the projection of the geometric position of the Sun relative to + the Earth onto the plane perpendicular to the Z axis. +Y axis completes the + right-handed system. The origin of this frame is the center of mass of the Earth.]] } } diff --git a/data/assets/scene/solarsystem/planets/earth/transforms_gsm_static.asset b/data/assets/scene/solarsystem/planets/earth/transforms_gsm_static.asset index 19048f6252..9ecb79559a 100644 --- a/data/assets/scene/solarsystem/planets/earth/transforms_gsm_static.asset +++ b/data/assets/scene/solarsystem/planets/earth/transforms_gsm_static.asset @@ -27,26 +27,27 @@ local GeocentricSolarMagnetosphericStatic = { GUI = { Name = "Geocentric Solar Magnetospheric Static", Path = "/Solar System/Planets/Earth", - Description =[[The Kernel for this is the same as - GSM (Geocentric Solar Magnetospheric), except it is using - ECLIPJ2000 instead of IAU_EARTH for the secondary axis. GSM is defind as: - +X is parallel to the geometric earth-sun position vector. - +Z axis is normalized component of north centered geomagnetic dipole - vector orthogonal to GSM +X axis. - +Y completes the right-handed frame. - - the origin of this frame is the center of mass of the Earth.]], - Hidden = true + Focusable = false, + Hidden = true, + Description =[[The Kernel for this is the same as GSM (Geocentric Solar + Magnetospheric), except it is using ECLIPJ2000 instead of IAU_EARTH for the + secondary axis. GSM is defind as: +X is parallel to the geometric earth-sun position + vector. +Z axis is normalized component of north centered geomagnetic dipole vector + orthogonal to GSM +X axis. +Y completes the right-handed frame. The origin of this + frame is the center of mass of the Earth.]] } } asset.onInitialize(function() openspace.spice.loadKernel(earthcentricKernels .. "GSM_static.tf") + openspace.addSceneGraphNode(GeocentricSolarMagnetosphericStatic ) end) asset.onDeinitialize(function() openspace.removeSceneGraphNode(GeocentricSolarMagnetosphericStatic ) + openspace.spice.unloadKernel(earthcentricKernels .. "GSM_static.tf") end) diff --git a/data/assets/scene/solarsystem/planets/jupiter/callisto/callisto.asset b/data/assets/scene/solarsystem/planets/jupiter/callisto/callisto.asset index 0fa2242dfe..c2c36b4bfc 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/callisto/callisto.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/callisto/callisto.asset @@ -72,6 +72,7 @@ local CallistoLabel = { GUI = { Name = "Callisto Label", Path = "/Solar System/Planets/Jupiter/Major Moons/Callisto", + Focusable = false, Description = "Label for Jupiter's moon Callisto" } } diff --git a/data/assets/scene/solarsystem/planets/jupiter/callisto/trail.asset b/data/assets/scene/solarsystem/planets/jupiter/callisto/trail.asset index a7a46d6c9a..ccfab97715 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/callisto/trail.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/callisto/trail.asset @@ -18,10 +18,16 @@ local CallistoTrail = { Period = 17.0, Resolution = 1000 }, - Tag = { "moonTrail_solarSystem", "moonTrail_giants", "moonTrail_jupiter", "moonTrail_major_jupiter" }, + Tag = { + "moonTrail_solarSystem", + "moonTrail_giants", + "moonTrail_jupiter", + "moonTrail_major_jupiter" + }, GUI = { Name = "Callisto Trail", - Path = "/Solar System/Planets/Jupiter/Major Moons/Callisto" + Path = "/Solar System/Planets/Jupiter/Major Moons/Callisto", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/jupiter/europa/europa.asset b/data/assets/scene/solarsystem/planets/jupiter/europa/europa.asset index 18460b39e2..b4ae20b4e4 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/europa/europa.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/europa/europa.asset @@ -71,6 +71,7 @@ local EuropaLabel = { GUI = { Name = "Europa Label", Path = "/Solar System/Planets/Jupiter/Major Moons/Europa", + Focusable = false, Description = "Label for Jupiter's moon Europa" } } diff --git a/data/assets/scene/solarsystem/planets/jupiter/europa/trail.asset b/data/assets/scene/solarsystem/planets/jupiter/europa/trail.asset index d0f6334f54..596aae4ce9 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/europa/trail.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/europa/trail.asset @@ -18,10 +18,16 @@ local EuropaTrail = { Period = 85.0 / 24.0, Resolution = 1000 }, - Tag = { "moonTrail_solarSystem", "moonTrail_giants", "moonTrail_jupiter", "moonTrail_major_jupiter" }, + Tag = { + "moonTrail_solarSystem", + "moonTrail_giants", + "moonTrail_jupiter", + "moonTrail_major_jupiter" + }, GUI = { Name = "Europa Trail", - Path = "/Solar System/Planets/Jupiter/Major Moons/Europa" + Path = "/Solar System/Planets/Jupiter/Major Moons/Europa", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/jupiter/ganymede/ganymede.asset b/data/assets/scene/solarsystem/planets/jupiter/ganymede/ganymede.asset index b3466d7e05..14f173e206 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/ganymede/ganymede.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/ganymede/ganymede.asset @@ -71,6 +71,7 @@ local GanymedeLabel = { GUI = { Name = "Ganymede Label", Path = "/Solar System/Planets/Jupiter/Major Moons/Ganymede", + Focusable = false, Description = "Label for Jupiter's moon Ganymede" } } diff --git a/data/assets/scene/solarsystem/planets/jupiter/ganymede/layers/colorlayers/ganymede_texture.asset b/data/assets/scene/solarsystem/planets/jupiter/ganymede/layers/colorlayers/ganymede_texture.asset index 13708b7291..e8bb5a03af 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/ganymede/layers/colorlayers/ganymede_texture.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/ganymede/layers/colorlayers/ganymede_texture.asset @@ -14,8 +14,7 @@ local Layer = { Identifier = "Texture", FilePath = texturesPath .. "ganymede.jpg", Enabled = asset.enabled, - ZIndex = 5, - CacheSettings = { Enabled = false } + ZIndex = 5 } diff --git a/data/assets/scene/solarsystem/planets/jupiter/ganymede/trail.asset b/data/assets/scene/solarsystem/planets/jupiter/ganymede/trail.asset index 7d9a810209..ce38b797d8 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/ganymede/trail.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/ganymede/trail.asset @@ -18,10 +18,16 @@ local GanymedeTrail = { Period = 172.0 / 24.0, Resolution = 1000 }, - Tag = { "moonTrail_solarSystem", "moonTrail_giants", "moonTrail_jupiter", "moonTrail_major_jupiter" }, + Tag = { + "moonTrail_solarSystem", + "moonTrail_giants", + "moonTrail_jupiter", + "moonTrail_major_jupiter" + }, GUI = { Name = "Ganymede Trail", - Path = "/Solar System/Planets/Jupiter/Major Moons/Ganymede" + Path = "/Solar System/Planets/Jupiter/Major Moons/Ganymede", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/jupiter/io/io.asset b/data/assets/scene/solarsystem/planets/jupiter/io/io.asset index 9fac665977..4ae1523109 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/io/io.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/io/io.asset @@ -71,6 +71,7 @@ local IoLabel = { GUI = { Name = "Io Label", Path = "/Solar System/Planets/Jupiter/Major Moons/Io", + Focusable = false, Description = "Label for Jupiter's moon Io" } } diff --git a/data/assets/scene/solarsystem/planets/jupiter/io/layers/colorlayers/io_texture.asset b/data/assets/scene/solarsystem/planets/jupiter/io/layers/colorlayers/io_texture.asset index 91fcc1f4c3..292bb5608c 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/io/layers/colorlayers/io_texture.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/io/layers/colorlayers/io_texture.asset @@ -14,8 +14,7 @@ local Layer = { Identifier = "Texture", FilePath = texturesPath .. "io.jpg", Enabled = asset.enabled, - ZIndex = 5, - CacheSettings = { Enabled = false } + ZIndex = 5 } diff --git a/data/assets/scene/solarsystem/planets/jupiter/io/trail.asset b/data/assets/scene/solarsystem/planets/jupiter/io/trail.asset index cc58f52492..6281348acc 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/io/trail.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/io/trail.asset @@ -18,10 +18,16 @@ local IoTrail = { Period = 42.0 / 24.0, Resolution = 1000 }, - Tag = { "moonTrail_solarSystem", "moonTrail_giants", "moonTrail_jupiter", "moonTrail_major_jupiter" }, + Tag = { + "moonTrail_solarSystem", + "moonTrail_giants", + "moonTrail_jupiter", + "moonTrail_major_jupiter" + }, GUI = { Name = "Io Trail", - Path = "/Solar System/Planets/Jupiter/Major Moons/Io" + Path = "/Solar System/Planets/Jupiter/Major Moons/Io", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/jupiter/jupiter.asset b/data/assets/scene/solarsystem/planets/jupiter/jupiter.asset index 5231ed1d1c..8c295811c9 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/jupiter.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/jupiter.asset @@ -60,7 +60,8 @@ local JupiterLabel = { Tag = { "solarsystem_labels" }, GUI = { Name = "Jupiter Label", - Path = "/Solar System/Planets/Jupiter" + Path = "/Solar System/Planets/Jupiter", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/jupiter/minor/ananke_group.asset b/data/assets/scene/solarsystem/planets/jupiter/minor/ananke_group.asset index 7c6e31f410..608cc6bec0 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/minor/ananke_group.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/minor/ananke_group.asset @@ -57,7 +57,8 @@ local S2010J2Trail = { }, GUI = { Name = "S/2010 J 2 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2010J2" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2010J2", + Focusable = false } } @@ -88,6 +89,7 @@ local S2010J2Label = { GUI = { Name = "S/2010 J 2 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2010J2", + Focusable = false, Description = "Label for Jupiter's moon S/2010 J 2 (Ananke group)" } } @@ -144,7 +146,8 @@ local ThelxinoeTrail = { }, GUI = { Name = "Thelxinoe Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/Thelxinoe" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/Thelxinoe", + Focusable = false } } @@ -175,6 +178,7 @@ local ThelxinoeLabel = { GUI = { Name = "Thelxinoe Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/Thelxinoe", + Focusable = false, Description = "Label for Jupiter's moon Thelxinoe (Ananke group)" } } @@ -231,7 +235,8 @@ local EuantheTrail = { }, GUI = { Name = "Euanthe Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/Euanthe" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/Euanthe", + Focusable = false } } @@ -262,6 +267,7 @@ local EuantheLabel = { GUI = { Name = "Euanthe Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/Euanthe", + Focusable = false, Description = "Label for Jupiter's moon Euanthe (Ananke group)" } } @@ -318,7 +324,8 @@ local IocasteTrail = { }, GUI = { Name = "Iocaste Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/Iocaste" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/Iocaste", + Focusable = false } } @@ -349,6 +356,7 @@ local IocasteLabel = { GUI = { Name = "Iocaste Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/Iocaste", + Focusable = false, Description = "Label for Jupiter's moon Iocaste (Ananke group)" } } @@ -405,7 +413,8 @@ local S2003J16Trail = { }, GUI = { Name = "S/2003 J 16 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2003J16" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2003J16", + Focusable = false } } @@ -436,6 +445,7 @@ local S2003J16Label = { GUI = { Name = "S/2003 J 16 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2003J16", + Focusable = false, Description = "Label for Jupiter's moon S/2003 J 16 (Ananke group)" } } @@ -492,7 +502,8 @@ local PraxidikeTrail = { }, GUI = { Name = "Praxidike Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/Praxidike" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/Praxidike", + Focusable = false } } @@ -523,6 +534,7 @@ local PraxidikeLabel = { GUI = { Name = "Praxidike Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/Praxidike", + Focusable = false, Description = "Label for Jupiter's moon Praxidike (Ananke group)" } } @@ -579,7 +591,8 @@ local HarpalykeTrail = { }, GUI = { Name = "Harpalyke Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/Harpalyke" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/Harpalyke", + Focusable = false } } @@ -610,6 +623,7 @@ local HarpalykeLabel = { GUI = { Name = "Harpalyke Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/Harpalyke", + Focusable = false, Description = "Label for Jupiter's moon Harpalyke (Ananke group)" } } @@ -666,7 +680,8 @@ local MnemeTrail = { }, GUI = { Name = "Mneme Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/Mneme" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/Mneme", + Focusable = false } } @@ -697,6 +712,7 @@ local MnemeLabel = { GUI = { Name = "Mneme Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/Mneme", + Focusable = false, Description = "Label for Jupiter's moon Mneme (Ananke group)" } } @@ -753,7 +769,8 @@ local HermippeTrail = { }, GUI = { Name = "Hermippe Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/Hermippe" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/Hermippe", + Focusable = false } } @@ -784,6 +801,7 @@ local HermippeLabel = { GUI = { Name = "Hermippe Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/Hermippe", + Focusable = false, Description = "Label for Jupiter's moon Hermippe (Ananke group)" } } @@ -840,7 +858,8 @@ local ThyoneTrail = { }, GUI = { Name = "Thyone Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/Thyone" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/Thyone", + Focusable = false } } @@ -871,6 +890,7 @@ local ThyoneLabel = { GUI = { Name = "Thyone Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/Thyone", + Focusable = false, Description = "Label for Jupiter's moon Thyone (Ananke group)" } } @@ -927,7 +947,8 @@ local AnankeTrail = { }, GUI = { Name = "Ananke Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/Ananke" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/Ananke", + Focusable = false } } @@ -958,6 +979,7 @@ local AnankeLabel = { GUI = { Name = "Ananke Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/Ananke", + Focusable = false, Description = "Label for Jupiter's moon Ananke (Ananke group)" } } @@ -1014,7 +1036,8 @@ local S2021J1Trail = { }, GUI = { Name = "S/2021 J 1 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2021J1" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2021J1", + Focusable = false } } @@ -1045,6 +1068,7 @@ local S2021J1Label = { GUI = { Name = "S/2021 J 1 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2021J1", + Focusable = false, Description = "Label for Jupiter's moon S/2021 J 1 (Ananke group)" } } @@ -1101,7 +1125,8 @@ local S2021J2Trail = { }, GUI = { Name = "S/2021 J 2 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2021J2" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2021J2", + Focusable = false } } @@ -1132,6 +1157,7 @@ local S2021J2Label = { GUI = { Name = "S/2021 J 2 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2021J2", + Focusable = false, Description = "Label for Jupiter's moon S/2021 J 2 (Ananke group)" } } @@ -1188,7 +1214,8 @@ local S2021J3Trail = { }, GUI = { Name = "S/2021 J 3 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2021J3" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2021J3", + Focusable = false } } @@ -1219,6 +1246,7 @@ local S2021J3Label = { GUI = { Name = "S/2021 J 3 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2021J3", + Focusable = false, Description = "Label for Jupiter's moon S/2021 J 3 (Ananke group)" } } @@ -1275,7 +1303,8 @@ local S2022J3Trail = { }, GUI = { Name = "S/2022 J 3 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2022J3" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2022J3", + Focusable = false } } @@ -1306,6 +1335,7 @@ local S2022J3Label = { GUI = { Name = "S/2022 J 3 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2022J3", + Focusable = false, Description = "Label for Jupiter's moon S/2022 J 3 (Ananke group)" } } @@ -1362,7 +1392,8 @@ local S2017J3Trail = { }, GUI = { Name = "S/2017 J 3 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2017J3" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2017J3", + Focusable = false } } @@ -1393,6 +1424,7 @@ local S2017J3Label = { GUI = { Name = "S/2017 J 3 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2017J3", + Focusable = false, Description = "Label for Jupiter's moon S/2017 J 3 (Ananke group)" } } @@ -1449,7 +1481,8 @@ local S2017J7Trail = { }, GUI = { Name = "S/2017 J 7 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2017J7" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2017J7", + Focusable = false } } @@ -1480,6 +1513,7 @@ local S2017J7Label = { GUI = { Name = "S/2017 J 7 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2017J7", + Focusable = false, Description = "Label for Jupiter's moon S/2017 J 7 (Ananke group)" } } @@ -1536,7 +1570,8 @@ local S2017J9Trail = { }, GUI = { Name = "S/2017 J 9 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2017J9" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2017J9", + Focusable = false } } @@ -1567,6 +1602,7 @@ local S2017J9Label = { GUI = { Name = "S/2017 J 9 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2017J9", + Focusable = false, Description = "Label for Jupiter's moon S/2017 J 9 (Ananke group)" } } @@ -1623,7 +1659,8 @@ local S2003J2Trail = { }, GUI = { Name = "S/2003 J 2 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2003J2" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2003J2", + Focusable = false } } @@ -1654,6 +1691,7 @@ local S2003J2Label = { GUI = { Name = "S/2003 J 2 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2003J2", + Focusable = false, Description = "Label for Jupiter's moon S/2003 J 2 (Ananke group)" } } @@ -1710,7 +1748,8 @@ local S2003J12Trail = { }, GUI = { Name = "S/2003 J 12 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2003J12" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2003J12", + Focusable = false } } @@ -1741,6 +1780,7 @@ local S2003J12Label = { GUI = { Name = "S/2003 J 12 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2003J12", + Focusable = false, Description = "Label for Jupiter's moon S/2003 J 12 (Ananke group)" } } diff --git a/data/assets/scene/solarsystem/planets/jupiter/minor/carme_group.asset b/data/assets/scene/solarsystem/planets/jupiter/minor/carme_group.asset index a4d05d4632..4ea6773058 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/minor/carme_group.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/minor/carme_group.asset @@ -57,7 +57,8 @@ local HerseTrail = { }, GUI = { Name = "Herse Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Herse" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Herse", + Focusable = false } } @@ -88,6 +89,7 @@ local HerseLabel = { GUI = { Name = "Herse Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Herse", + Focusable = false, Description = "Label for Jupiter's moon Herse (Carme group)" } } @@ -144,7 +146,8 @@ local AitneTrail = { }, GUI = { Name = "Aitne Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Aitne" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Aitne", + Focusable = false } } @@ -175,6 +178,7 @@ local AitneLabel = { GUI = { Name = "Aitne Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Aitne", + Focusable = false, Description = "Label for Jupiter's moon Aitne (Carme group)" } } @@ -231,7 +235,8 @@ local KaleTrail = { }, GUI = { Name = "Kale Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Kale" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Kale", + Focusable = false } } @@ -262,6 +267,7 @@ local KaleLabel = { GUI = { Name = "Kale Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Kale", + Focusable = false, Description = "Label for Jupiter's moon Kale (Carme group)" } } @@ -318,7 +324,8 @@ local TaygeteTrail = { }, GUI = { Name = "Taygete Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Taygete" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Taygete", + Focusable = false } } @@ -349,6 +356,7 @@ local TaygeteLabel = { GUI = { Name = "Taygete Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Taygete", + Focusable = false, Description = "Label for Jupiter's moon Taygete (Carme group)" } } @@ -405,7 +413,8 @@ local ChaldeneTrail = { }, GUI = { Name = "Chaldene Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Chaldene" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Chaldene", + Focusable = false } } @@ -436,6 +445,7 @@ local ChaldeneLabel = { GUI = { Name = "Chaldene Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Chaldene", + Focusable = false, Description = "Label for Jupiter's moon Chaldene (Carme group)" } } @@ -492,7 +502,8 @@ local ErinomeTrail = { }, GUI = { Name = "Erinome Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Erinome" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Erinome", + Focusable = false } } @@ -523,6 +534,7 @@ local ErinomeLabel = { GUI = { Name = "Erinome Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Erinome", + Focusable = false, Description = "Label for Jupiter's moon Erinome (Carme group)" } } @@ -579,7 +591,8 @@ local KallichoreTrail = { }, GUI = { Name = "Kallichore Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Kallichore" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Kallichore", + Focusable = false } } @@ -610,6 +623,7 @@ local KallichoreLabel = { GUI = { Name = "Kallichore Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Kallichore", + Focusable = false, Description = "Label for Jupiter's moon Kallichore (Carme group)" } } @@ -666,7 +680,8 @@ local KalykeTrail = { }, GUI = { Name = "Kalyke Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Kalyke" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Kalyke", + Focusable = false } } @@ -697,6 +712,7 @@ local KalykeLabel = { GUI = { Name = "Kalyke Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Kalyke", + Focusable = false, Description = "Label for Jupiter's moon Kalyke (Carme group)" } } @@ -753,7 +769,8 @@ local PasitheeTrail = { }, GUI = { Name = "Pasithee Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Pasithee" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Pasithee", + Focusable = false } } @@ -784,6 +801,7 @@ local PasitheeLabel = { GUI = { Name = "Pasithee Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Pasithee", + Focusable = false, Description = "Label for Jupiter's moon Pasithee (Carme group)" } } @@ -840,7 +858,8 @@ local S2010J1Trail = { }, GUI = { Name = "S/2010 J 1 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2010J1" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2010J1", + Focusable = false } } @@ -871,6 +890,7 @@ local S2010J1Label = { GUI = { Name = "S/2010 J 1 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2010J1", + Focusable = false, Description = "Label for Jupiter's moon S2010J1 (Carme group)" } } @@ -927,7 +947,8 @@ local EukeladeTrail = { }, GUI = { Name = "Eukelade Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Eukelade" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Eukelade", + Focusable = false } } @@ -958,6 +979,7 @@ local EukeladeLabel = { GUI = { Name = "Eukelade Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Eukelade", + Focusable = false, Description = "Label for Jupiter's moon Eukelade (Carme group)" } } @@ -1014,7 +1036,8 @@ local ArcheTrail = { }, GUI = { Name = "Arche Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Arche" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Arche", + Focusable = false } } @@ -1045,6 +1068,7 @@ local ArcheLabel = { GUI = { Name = "Arche Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Arche", + Focusable = false, Description = "Label for Jupiter's moon Arche (Carme group)" } } @@ -1101,7 +1125,8 @@ local IsonoeTrail = { }, GUI = { Name = "Isonoe Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Isonoe" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Isonoe", + Focusable = false } } @@ -1132,6 +1157,7 @@ local IsonoeLabel = { GUI = { Name = "Isonoe Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Isonoe", + Focusable = false, Description = "Label for Jupiter's moon Isonoe (Carme group)" } } @@ -1188,7 +1214,8 @@ local CarmeTrail = { }, GUI = { Name = "Carme Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Carme" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Carme", + Focusable = false } } @@ -1219,6 +1246,7 @@ local CarmeLabel = { GUI = { Name = "Carme Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/Carme", + Focusable = false, Description = "Label for Jupiter's moon Carme (Carme group)" } } @@ -1275,7 +1303,8 @@ local S2003J5Trail = { }, GUI = { Name = "S/2003 J 5 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2003J5" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2003J5", + Focusable = false } } @@ -1306,6 +1335,7 @@ local S2003J5Label = { GUI = { Name = "S/2003 J 5 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2003J5", + Focusable = false, Description = "Label for Jupiter's moon S2003J5 (Carme group)" } } @@ -1362,7 +1392,8 @@ local S2018J3Trail = { }, GUI = { Name = "S/2018 J 3 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2018J3" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2018J3", + Focusable = false } } @@ -1393,6 +1424,7 @@ local S2018J3Label = { GUI = { Name = "S/2018 J 3 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2018J3", + Focusable = false, Description = "Label for Jupiter's moon S2018J3 (Carme group)" } } @@ -1449,7 +1481,8 @@ local S2021J4Trail = { }, GUI = { Name = "S/2021 J 4 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2021J4" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2021J4", + Focusable = false } } @@ -1480,6 +1513,7 @@ local S2021J4Label = { GUI = { Name = "S/2021 J 4 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2021J4", + Focusable = false, Description = "Label for Jupiter's moon S2021J4 (Carme group)" } } @@ -1536,7 +1570,8 @@ local S2021J5Trail = { }, GUI = { Name = "S/2021 J 5 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2021J5" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2021J5", + Focusable = false } } @@ -1567,6 +1602,7 @@ local S2021J5Label = { GUI = { Name = "S/2021 J 5 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2021J5", + Focusable = false, Description = "Label for Jupiter's moon S2021J5 (Carme group)" } } @@ -1623,7 +1659,8 @@ local S2021J6Trail = { }, GUI = { Name = "S/2021 J 6 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2021J6" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2021J6", + Focusable = false } } @@ -1654,6 +1691,7 @@ local S2021J6Label = { GUI = { Name = "S/2021 J 6 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2021J6", + Focusable = false, Description = "Label for Jupiter's moon S2021J6 (Carme group)" } } @@ -1710,7 +1748,8 @@ local S2016J3Trail = { }, GUI = { Name = "S/2016 J 3 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2016J3" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2016J3", + Focusable = false } } @@ -1741,6 +1780,7 @@ local S2016J3Label = { GUI = { Name = "S/2016 J 3 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2016J3", + Focusable = false, Description = "Label for Jupiter's moon S2016J3 (Carme group)" } } @@ -1797,7 +1837,8 @@ local S2022J1Trail = { }, GUI = { Name = "S/2022 J 1 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2022J1" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2022J1", + Focusable = false } } @@ -1828,6 +1869,7 @@ local S2022J1Label = { GUI = { Name = "S/2022 J 1 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2022J1", + Focusable = false, Description = "Label for Jupiter's moon S2022J1 (Carme group)" } } @@ -1884,7 +1926,8 @@ local S2022J2Trail = { }, GUI = { Name = "S/2022 J 2 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2022J2" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2022J2", + Focusable = false } } @@ -1915,6 +1958,7 @@ local S2022J2Label = { GUI = { Name = "S/2022 J 2 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2022J2", + Focusable = false, Description = "Label for Jupiter's moon S2022J2 (Carme group)" } } @@ -1971,7 +2015,8 @@ local S2017J2Trail = { }, GUI = { Name = "S/2017 J 2 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2017J2" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2017J2", + Focusable = false } } @@ -2002,6 +2047,7 @@ local S2017J2Label = { GUI = { Name = "S/2017 J 2 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2017J2", + Focusable = false, Description = "Label for Jupiter's moon S2017J2 (Carme group)" } } @@ -2058,7 +2104,8 @@ local S2017J5Trail = { }, GUI = { Name = "S/2017 J 5 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2017J5" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2017J5", + Focusable = false } } @@ -2089,6 +2136,7 @@ local S2017J5Label = { GUI = { Name = "S/2017 J 5 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2017J5", + Focusable = false, Description = "Label for Jupiter's moon S2017J5 (Carme group)" } } @@ -2145,7 +2193,8 @@ local S2017J8Trail = { }, GUI = { Name = "S/2017 J 8 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2017J8" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2017J8", + Focusable = false } } @@ -2176,6 +2225,7 @@ local S2017J8Label = { GUI = { Name = "S/2017 J 8 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2017J8", + Focusable = false, Description = "Label for Jupiter's moon S2017J8 (Carme group)" } } @@ -2232,7 +2282,8 @@ local S2011J1Trail = { }, GUI = { Name = "S/2011 J 1 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2011J1" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2011J1", + Focusable = false } } @@ -2263,6 +2314,7 @@ local S2011J1Label = { GUI = { Name = "S/2011 J 1 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2011J1", + Focusable = false, Description = "Label for Jupiter's moon S2011J1 (Carme group)" } } @@ -2319,7 +2371,8 @@ local S2003J9Trail = { }, GUI = { Name = "S/2003 J 9 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2003J9" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2003J9", + Focusable = false } } @@ -2350,6 +2403,7 @@ local S2003J9Label = { GUI = { Name = "S/2003 J 9 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2003J9", + Focusable = false, Description = "Label for Jupiter's moon S2003J9 (Carme group)" } } @@ -2406,7 +2460,8 @@ local S2003J10Trail = { }, GUI = { Name = "S/2003 J 10 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2003J10" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2003J10", + Focusable = false } } @@ -2437,6 +2492,7 @@ local S2003J10Label = { GUI = { Name = "S/2003 J 10 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carme Group/S2003J10", + Focusable = false, Description = "Label for Jupiter's moon S2003J10 (Carme group)" } } diff --git a/data/assets/scene/solarsystem/planets/jupiter/minor/carpo_group.asset b/data/assets/scene/solarsystem/planets/jupiter/minor/carpo_group.asset index 78b8c10e45..c17e5be2f0 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/minor/carpo_group.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/minor/carpo_group.asset @@ -57,7 +57,8 @@ local CarpoTrail = { }, GUI = { Name = "Carpo Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Carpo Group/Carpo" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Carpo Group/Carpo", + Focusable = false } } @@ -88,6 +89,7 @@ local CarpoLabel = { GUI = { Name = "Carpo Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carpo Group/Carpo", + Focusable = false, Description = "Label for Jupiter's moon Carpo (Carpo group)" } } @@ -119,6 +121,7 @@ local CarpoLabelNear = { GUI = { Name = "Carpo Label (Near)", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carpo Group/Carpo", + Focusable = false, Description = "Transitional Label for close-range viewing of Carpo (Carpo group)" } } @@ -175,7 +178,8 @@ local S2018J4Trail = { }, GUI = { Name = "S/2018 J 4 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Carpo Group/S2018J4" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Carpo Group/S2018J4", + Focusable = false } } @@ -206,6 +210,7 @@ local S2018J4Label = { GUI = { Name = "S/2018 J 4 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carpo Group/S2018J4", + Focusable = false, Description = "Label for Jupiter's moon S2018J4 (Carpo group)" } } @@ -237,6 +242,7 @@ local S2018J4LabelNear = { GUI = { Name = "S2018J4 Label (Near)", Path = "/Solar System/Planets/Jupiter/Minor Moons/Carpo Group/S2018J4", + Focusable = false, Description = "Transitional Label for close-range viewing of S2018J4 (Carpo group)" } } diff --git a/data/assets/scene/solarsystem/planets/jupiter/minor/himalia_group.asset b/data/assets/scene/solarsystem/planets/jupiter/minor/himalia_group.asset index cdbb1c3fb9..7d4c46380d 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/minor/himalia_group.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/minor/himalia_group.asset @@ -57,7 +57,8 @@ local LedaTrail = { }, GUI = { Name = "Leda Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Himalia Group/Leda" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Himalia Group/Leda", + Focusable = false } } @@ -88,6 +89,7 @@ local LedaLabel = { GUI = { Name = "Leda Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Himalia Group/Leda", + Focusable = false, Description = "Label for Jupiter's moon Leda (Himalia group)" } } @@ -144,7 +146,8 @@ local HimaliaTrail = { }, GUI = { Name = "Himalia Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Himalia Group/Himalia" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Himalia Group/Himalia", + Focusable = false } } @@ -175,6 +178,7 @@ local HimaliaLabel = { GUI = { Name = "Himalia Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Himalia Group/Himalia", + Focusable = false, Description = "Label for Jupiter's moon Himalia (Himalia group)" } } @@ -231,7 +235,8 @@ local LysitheaTrail = { }, GUI = { Name = "Lysithea Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Himalia Group/Lysithea" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Himalia Group/Lysithea", + Focusable = false } } @@ -262,6 +267,7 @@ local LysitheaLabel = { GUI = { Name = "Lysithea Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Himalia Group/Lysithea", + Focusable = false, Description = "Label for Jupiter's moon Lysithea (Himalia group)" } } @@ -318,7 +324,8 @@ local ElaraTrail = { }, GUI = { Name = "Elara Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Himalia Group/Elara" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Himalia Group/Elara", + Focusable = false } } @@ -349,6 +356,7 @@ local ElaraLabel = { GUI = { Name = "Elara Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Himalia Group/Elara", + Focusable = false, Description = "Label for Jupiter's moon Elara (Himalia group)" } } @@ -405,7 +413,8 @@ local DiaTrail = { }, GUI = { Name = "Dia Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Himalia Group/Dia" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Himalia Group/Dia", + Focusable = false } } @@ -436,6 +445,7 @@ local DiaLabel = { GUI = { Name = "Dia Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Himalia Group/Dia", + Focusable = false, Description = "Label for Jupiter's moon Dia (Himalia group)" } } @@ -492,7 +502,8 @@ local S2011J3Trail = { }, GUI = { Name = "S/2011 J 3 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Himalia Group/S2011J3" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Himalia Group/S2011J3", + Focusable = false } } @@ -523,6 +534,7 @@ local S2011J3Label = { GUI = { Name = "S/2011 J 3 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Himalia Group/S2011J3", + Focusable = false, Description = "Label for Jupiter's moon S2011J3 (Himalia group)" } } @@ -579,7 +591,8 @@ local S2018J2Trail = { }, GUI = { Name = "S/2018 J 2 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Himalia Group/S2018J2" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Himalia Group/S2018J2", + Focusable = false } } @@ -610,6 +623,7 @@ local S2018J2Label = { GUI = { Name = "S/2018 J 2 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Himalia Group/S2018J2", + Focusable = false, Description = "Label for Jupiter's moon S2018J2 (Himalia group)" } } @@ -666,7 +680,8 @@ local PandiaTrail = { }, GUI = { Name = "Pandia Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Himalia Group/Pandia" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Himalia Group/Pandia", + Focusable = false } } @@ -697,6 +712,7 @@ local PandiaLabel = { GUI = { Name = "Pandia Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Himalia Group/Pandia", + Focusable = false, Description = "Label for Jupiter's moon Pandia (Himalia group)" } } @@ -753,7 +769,8 @@ local ErsaTrail = { }, GUI = { Name = "Ersa Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Himalia Group/Ersa" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Himalia Group/Ersa", + Focusable = false } } @@ -784,6 +801,7 @@ local ErsaLabel = { GUI = { Name = "Ersa Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Himalia Group/Ersa", + Focusable = false, Description = "Label for Jupiter's moon Ersa (Himalia group)" } } diff --git a/data/assets/scene/solarsystem/planets/jupiter/minor/inner_group.asset b/data/assets/scene/solarsystem/planets/jupiter/minor/inner_group.asset index a582070c4f..f885f6cf3c 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/minor/inner_group.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/minor/inner_group.asset @@ -56,7 +56,8 @@ local MetisTrail = { }, GUI = { Name = "Metis Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Inner Group/Metis" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Inner Group/Metis", + Focusable = false } } @@ -87,6 +88,7 @@ local MetisLabel = { GUI = { Name = "Metis Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Inner Group/Metis", + Focusable = false, Description = "Label for Jupiter's moon Metis (inner group)" } } @@ -143,7 +145,8 @@ local AdrasteaTrail = { }, GUI = { Name = "Adrastea Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Inner Group/Adrastea" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Inner Group/Adrastea", + Focusable = false } } @@ -174,6 +177,7 @@ local AdrasteaLabel = { GUI = { Name = "Adrastea Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Inner Group/Adrastea", + Focusable = false, Description = "Label for Jupiter's moon Adrastea (inner group)" } } @@ -230,7 +234,8 @@ local AmaltheaTrail = { }, GUI = { Name = "Amalthea Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Inner Group/Amalthea" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Inner Group/Amalthea", + Focusable = false } } @@ -261,6 +266,7 @@ local AmaltheaLabel = { GUI = { Name = "Amalthea Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Inner Group/Amalthea", + Focusable = false, Description = "Label for Jupiter's moon Amalthea (inner group)" } } @@ -317,7 +323,8 @@ local ThebeTrail = { }, GUI = { Name = "Thebe Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Inner Group/Thebe" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Inner Group/Thebe", + Focusable = false } } @@ -348,6 +355,7 @@ local ThebeLabel = { GUI = { Name = "Thebe Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Inner Group/Thebe", + Focusable = false, Description = "Label for Jupiter's moon Thebe (inner group)" } } diff --git a/data/assets/scene/solarsystem/planets/jupiter/minor/other_groups.asset b/data/assets/scene/solarsystem/planets/jupiter/minor/other_groups.asset index f2d49dc414..9033957fdf 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/minor/other_groups.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/minor/other_groups.asset @@ -56,7 +56,8 @@ local EuphemeTrail = { }, GUI = { Name = "Eupheme Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Other Group/Eupheme" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Other Group/Eupheme", + Focusable = false } } @@ -87,6 +88,7 @@ local EuphemeLabel = { GUI = { Name = "Eupheme Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Other Group/Eupheme", + Focusable = false, Description = "Label for Jupiter's moon Eupheme (other group)" } } @@ -143,7 +145,8 @@ local S2003J19Trail = { }, GUI = { Name = "S/2003 J 19 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2003J19" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2003J19", + Focusable = false } } @@ -174,6 +177,7 @@ local S2003J19Label = { GUI = { Name = "S/2003 J 19 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/S2003J19", + Focusable = false, Description = "Label for Jupiter's moon S/2003 J 19 (other group)" } } @@ -230,7 +234,8 @@ local ValetudoTrail = { }, GUI = { Name = "Valetudo Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/Valetudo" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/Valetudo", + Focusable = false } } @@ -261,6 +266,7 @@ local ValetudoLabel = { GUI = { Name = "Valetudo Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Ananke Group/Valetudo", + Focusable = false, Description = "Label for Jupiter's moon Valetudo (other group)" } } diff --git a/data/assets/scene/solarsystem/planets/jupiter/minor/pasiphae_group.asset b/data/assets/scene/solarsystem/planets/jupiter/minor/pasiphae_group.asset index e31425a8f2..e98b1acde2 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/minor/pasiphae_group.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/minor/pasiphae_group.asset @@ -57,7 +57,8 @@ local EuporieTrail = { }, GUI = { Name = "Euporie Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Euporie" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Euporie", + Focusable = false } } @@ -88,6 +89,7 @@ local EuporieLabel = { GUI = { Name = "Euporie Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Euporie", + Focusable = false, Description = "Label for Jupiter's moon Euporie (Pasiphae group)" } } @@ -144,7 +146,8 @@ local S2003J18Trail = { }, GUI = { Name = "S/2003 J 18 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/S2003J18" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/S2003J18", + Focusable = false } } @@ -175,6 +178,7 @@ local S2003J18Label = { GUI = { Name = "S/2003 J 18 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/S2003J18", + Focusable = false, Description = "Label for Jupiter's moon S/2003 J 18 (Pasiphae group)" } } @@ -231,7 +235,8 @@ local HelikeTrail = { }, GUI = { Name = "Helike Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Helike" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Helike", + Focusable = false } } @@ -262,6 +267,7 @@ local HelikeLabel = { GUI = { Name = "Helike Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Helike", + Focusable = false, Description = "Label for Jupiter's moon Helike (Pasiphae group)" } } @@ -318,7 +324,8 @@ local OrthosieTrail = { }, GUI = { Name = "Orthosie Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Orthosie" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Orthosie", + Focusable = false } } @@ -349,6 +356,7 @@ local OrthosieLabel = { GUI = { Name = "Orthosie Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Orthosie", + Focusable = false, Description = "Label for Jupiter's moon Orthosie (Pasiphae group)" } } @@ -405,7 +413,8 @@ local S2016J1Trail = { }, GUI = { Name = "S/2016 J 1 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/S2016J1" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/S2016J1", + Focusable = false } } @@ -436,6 +445,7 @@ local S2016J1Label = { GUI = { Name = "S/2016 J 1 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/S2016J1", + Focusable = false, Description = "Label for Jupiter's moon S/2016 J 1 (Pasiphae group)" } } @@ -492,7 +502,8 @@ local S2003J15Trail = { }, GUI = { Name = "S/2003 J 15 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/S2003J15" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/S2003J15", + Focusable = false } } @@ -523,6 +534,7 @@ local S2003J15Label = { GUI = { Name = "S/2003 J 15 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/S2003J15", + Focusable = false, Description = "Label for Jupiter's moon OrthosiS/2003 J 15e (Pasiphae group)" } } @@ -579,7 +591,8 @@ local AoedeTrail = { }, GUI = { Name = "Aoede Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Aoede" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Aoede", + Focusable = false } } @@ -610,6 +623,7 @@ local AoedeLabel = { GUI = { Name = "Aoede Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Aoede", + Focusable = false, Description = "Label for Jupiter's moon Aoede (Pasiphae group)" } } @@ -666,7 +680,8 @@ local CallirrhoeTrail = { }, GUI = { Name = "Callirrhoe Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Callirrhoe" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Callirrhoe", + Focusable = false } } @@ -697,6 +712,7 @@ local CallirrhoeLabel = { GUI = { Name = "Callirrhoe Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Callirrhoe", + Focusable = false, Description = "Label for Jupiter's moon Callirrhoe (Pasiphae group)" } } @@ -753,7 +769,8 @@ local EurydomeTrail = { }, GUI = { Name = "Eurydome Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Eurydome" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Eurydome", + Focusable = false } } @@ -784,6 +801,7 @@ local EurydomeLabel = { GUI = { Name = "Eurydome Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Eurydome", + Focusable = false, Description = "Label for Jupiter's moon Eurydome (Pasiphae group)" } } @@ -840,7 +858,8 @@ local KoreTrail = { }, GUI = { Name = "Kore Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Kore" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Kore", + Focusable = false } } @@ -871,6 +890,7 @@ local KoreLabel = { GUI = { Name = "Kore Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Kore", + Focusable = false, Description = "Label for Jupiter's moon Kore (Pasiphae group)" } } @@ -927,7 +947,8 @@ local CylleneTrail = { }, GUI = { Name = "Cyllene Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Cyllene" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Cyllene", + Focusable = false } } @@ -958,6 +979,7 @@ local CylleneLabel = { GUI = { Name = "Cyllene Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Cyllene", + Focusable = false, Description = "Label for Jupiter's moon Cyllene (Pasiphae group)" } } @@ -1014,7 +1036,8 @@ local S2011J2Trail = { }, GUI = { Name = "S/2011 J 2 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/S2011J2" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/S2011J2", + Focusable = false } } @@ -1045,6 +1068,7 @@ local S2011J2Label = { GUI = { Name = "S/2011 J 2 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/S2011J2", + Focusable = false, Description = "Label for Jupiter's moon S/2011 J 2 (Pasiphae group)" } } @@ -1101,7 +1125,8 @@ local S2017J1Trail = { }, GUI = { Name = "S/2017 J 1 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/S2017J1" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/S2017J1", + Focusable = false } } @@ -1132,6 +1157,7 @@ local S2017J1Label = { GUI = { Name = "S/2017 J 1 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/S2017J1", + Focusable = false, Description = "Label for Jupiter's moon S/2017 J 1 (Pasiphae group)" } } @@ -1188,7 +1214,8 @@ local S2003J4Trail = { }, GUI = { Name = "S/2003 J 4 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/S2003J4" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/S2003J4", + Focusable = false } } @@ -1219,6 +1246,7 @@ local S2003J4Label = { GUI = { Name = "S/2003 J 4 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/S2003J4", + Focusable = false, Description = "Label for Jupiter's moon S/2003 J 4 (Pasiphae group)" } } @@ -1275,7 +1303,8 @@ local PasiphaeTrail = { }, GUI = { Name = "Pasiphae Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Pasiphae" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Pasiphae", + Focusable = false } } @@ -1306,6 +1335,7 @@ local PasiphaeLabel = { GUI = { Name = "Pasiphae Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Pasiphae", + Focusable = false, Description = "Label for Jupiter's moon Pasiphae (Pasiphae group)" } } @@ -1362,7 +1392,8 @@ local HegemoneTrail = { }, GUI = { Name = "Hegemone Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Hegemone" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Hegemone", + Focusable = false } } @@ -1393,6 +1424,7 @@ local HegemoneLabel = { GUI = { Name = "Hegemone Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Hegemone", + Focusable = false, Description = "Label for Jupiter's moon Hegemone (Pasiphae group)" } } @@ -1449,7 +1481,8 @@ local SinopeTrail = { }, GUI = { Name = "Sinope Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Sinope" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Sinope", + Focusable = false } } @@ -1480,6 +1513,7 @@ local SinopeLabel = { GUI = { Name = "Sinope Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Sinope", + Focusable = false, Description = "Label for Jupiter's moon Sinope (Pasiphae group)" } } @@ -1536,7 +1570,8 @@ local SpondeTrail = { }, GUI = { Name = "Sponde Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Sponde" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Sponde", + Focusable = false } } @@ -1567,6 +1602,7 @@ local SpondeLabel = { GUI = { Name = "Sponde Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Sponde", + Focusable = false, Description = "Label for Jupiter's moon Sponde (Pasiphae group)" } } @@ -1623,7 +1659,8 @@ local AutonoeTrail = { }, GUI = { Name = "Autonoe Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Autonoe" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Autonoe", + Focusable = false } } @@ -1654,6 +1691,7 @@ local AutonoeLabel = { GUI = { Name = "Autonoe Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Autonoe", + Focusable = false, Description = "Label for Jupiter's moon Autonoe (Pasiphae group)" } } @@ -1710,7 +1748,8 @@ local MegacliteTrail = { }, GUI = { Name = "Megaclite Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Megaclite" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Megaclite", + Focusable = false } } @@ -1741,6 +1780,7 @@ local MegacliteLabel = { GUI = { Name = "Megaclite Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/Megaclite", + Focusable = false, Description = "Label for Jupiter's moon Megaclite (Pasiphae group)" } } @@ -1797,7 +1837,8 @@ local S2016J4Trail = { }, GUI = { Name = "S/2016 J 4 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/S2016J4" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/S2016J4", + Focusable = false } } @@ -1828,6 +1869,7 @@ local S2016J4Label = { GUI = { Name = "S/2016 J 4 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/S2016J4", + Focusable = false, Description = "Label for Jupiter's moon S/2016 J 4 (Pasiphae group)" } } @@ -1884,7 +1926,8 @@ local S2017J6Trail = { }, GUI = { Name = "S/2017 J 6 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/S2017J6" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/S2017J6", + Focusable = false } } @@ -1915,6 +1958,7 @@ local S2017J6Label = { GUI = { Name = "S/2017 J 6 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/S2017J6", + Focusable = false, Description = "Label for Jupiter's moon S/2017 J 6 (Pasiphae group)" } } @@ -1971,7 +2015,8 @@ local S2003J23Trail = { }, GUI = { Name = "S/2003 J 23 Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/S2003J23" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/S2003J23", + Focusable = false } } @@ -2002,6 +2047,7 @@ local S2003J23Label = { GUI = { Name = "S/2003 J 23 Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Pasiphae Group/S2003J23", + Focusable = false, Description = "Label for Jupiter's moon S/2003 J 23 (Pasiphae group)" } } diff --git a/data/assets/scene/solarsystem/planets/jupiter/minor/themisto_group.asset b/data/assets/scene/solarsystem/planets/jupiter/minor/themisto_group.asset index d353185aee..0c533b6860 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/minor/themisto_group.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/minor/themisto_group.asset @@ -56,7 +56,8 @@ local ThemistoTrail = { }, GUI = { Name = "Themisto Trail", - Path = "/Solar System/Planets/Jupiter/Minor Moons/Themisto Group/Themisto" + Path = "/Solar System/Planets/Jupiter/Minor Moons/Themisto Group/Themisto", + Focusable = false } } @@ -87,6 +88,7 @@ local ThemistoLabel = { GUI = { Name = "Themisto Label", Path = "/Solar System/Planets/Jupiter/Minor Moons/Themisto Group/Themisto", + Focusable = false, Description = "Label for Jupiter's moon Themisto (Themisto group)" } } diff --git a/data/assets/scene/solarsystem/planets/jupiter/minor_moons.asset b/data/assets/scene/solarsystem/planets/jupiter/minor_moons.asset index 83641da904..4c505acbf0 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/minor_moons.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/minor_moons.asset @@ -13,21 +13,8 @@ local JupiterMinorMoonsOn = { Identifier = "os.solarsystem.JupiterMinorMoonsOn", Name = "Turn ON minor moons and trails", Command = [[ - local trails = openspace.property("{moonTrail_minor_jupiter}.Renderable.Enabled") - local trails_fade = openspace.property("{moonTrail_minor_jupiter}.Renderable.Fade") - - local moons = openspace.property("{moon_minor_jupiter}.Renderable.Enabled") - local moons_fade = openspace.property("{moon_minor_jupiter}.Renderable.Fade") - - for i, v in pairs(trails_fade) do - openspace.setPropertyValueSingle(trails[i], true) - openspace.setPropertyValueSingle(v, 1, 2, "Linear") - end - - for i, v in pairs(moons_fade) do - openspace.setPropertyValueSingle(moons[i], true) - openspace.setPropertyValueSingle(v, 1, 2, "Linear") - end + openspace.fadeIn("{moonTrail_minor_jupiter}.Renderable") + openspace.fadeIn("{moon_minor_jupiter}.Renderable") ]], Documentation = "Turn ON Jupiter's minor moons and their trails", GuiPath = "/Solar System/Jupiter", @@ -38,31 +25,8 @@ local JupiterMinorMoonsOff = { Identifier = "os.solarsystem.JupiterMinorMoonsOff", Name = "Turn OFF minors moon and trails", Command = [[ - local trails = openspace.property("{moonTrail_minor_jupiter}.Renderable.Enabled") - local trails_fade = openspace.property("{moonTrail_minor_jupiter}.Renderable.Fade") - - local moons = openspace.property("{moon_minor_jupiter}.Renderable.Enabled") - local moons_fade = openspace.property("{moon_minor_jupiter}.Renderable.Fade") - - for i, v in pairs(trails_fade) do - openspace.setPropertyValueSingle( - v, - 0, - 2, - "Linear", - "openspace.setPropertyValueSingle('" .. trails[i] .. "', false)" - ) - end - - for i, v in pairs(moons_fade) do - openspace.setPropertyValueSingle( - v, - 0, - 2, - "Linear", - "openspace.setPropertyValueSingle('" .. moons[i] .. "', false)" - ) - end + openspace.fadeOut("{moonTrail_minor_jupiter}.Renderable") + openspace.fadeOut("{moon_minor_jupiter}.Renderable") ]], Documentation = "Turn OFF Jupiter's minor moons and their trails", GuiPath = "/Solar System/Jupiter", diff --git a/data/assets/scene/solarsystem/planets/jupiter/trail.asset b/data/assets/scene/solarsystem/planets/jupiter/trail.asset index 45c8633c63..dbe739106a 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/trail.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/trail.asset @@ -20,7 +20,8 @@ local JupiterTrail = { Tag = { "planetTrail_solarSystem", "planetTrail_giants" }, GUI = { Name = "Jupiter Trail", - Path = "/Solar System/Planets/Jupiter" + Path = "/Solar System/Planets/Jupiter", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/jupiter/trail_barycenter.asset b/data/assets/scene/solarsystem/planets/jupiter/trail_barycenter.asset index d480d1a503..aa08f555b5 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/trail_barycenter.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/trail_barycenter.asset @@ -21,7 +21,8 @@ local JupiterBarycenterTrail = { Tag = { "planetTrail_solarSystem", "planetTrail_giants" }, GUI = { Name = "Jupiter Barycenter Trail", - Path = "/Solar System/Planets/Jupiter" + Path = "/Solar System/Planets/Jupiter", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/jupiter/trail_earth.asset b/data/assets/scene/solarsystem/planets/jupiter/trail_earth.asset index ece03e2ec5..c318d51bc3 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/trail_earth.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/trail_earth.asset @@ -22,7 +22,8 @@ local JupiterTrailEarth = { Tag = { "planetTrail_solarSystem_alt", "planetTrail_terrestrial_alt" }, GUI = { Name = "Jupiter trail from Earth", - Path = "/Solar System/Planets/Jupiter" + Path = "/Solar System/Planets/Jupiter", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/jupiter/transforms.asset b/data/assets/scene/solarsystem/planets/jupiter/transforms.asset index 77636066a9..6eb644cd21 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/transforms.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/transforms.asset @@ -16,6 +16,7 @@ local JupiterBarycenter = { GUI = { Name = "Jupiter Barycenter", Path = "/Solar System/Planets/Jupiter", + Focusable = false, Hidden = true } } diff --git a/data/assets/scene/solarsystem/planets/mars/atmosphere.asset b/data/assets/scene/solarsystem/planets/mars/atmosphere.asset index d66b766f24..f93d6fa3c2 100644 --- a/data/assets/scene/solarsystem/planets/mars/atmosphere.asset +++ b/data/assets/scene/solarsystem/planets/mars/atmosphere.asset @@ -3,53 +3,54 @@ local transforms = asset.require("./mars") local Atmosphere = { - Identifier = "MarsAtmosphere", - Parent = transforms.Mars.Identifier, - Renderable = { - Type = "RenderableAtmosphere", - -- Atmosphere radius in Km - AtmosphereHeight = 3463.17495 - 3386.190, - PlanetRadius = 3386.190, - PlanetAverageGroundReflectance = 0.1, - GroundRadianceEmission = 0.37, - SunIntensity = 13.1, - MieScatteringExtinctionPropCoefficient = 0.23862, - Rayleigh = { - Coefficients = { - -- Wavelengths are given in 10^-9m - Wavelengths = { 680, 550, 440 }, - -- Reflection coefficients are given in km^-1 - Scattering = { 0.019918, 0.01357, 0.00575 } - -- In Rayleigh scattering, the coefficients of - -- absorption and scattering are the same. - }, - -- Thickness of atmosphere if its density were uniform, in Km - H_R = 10.43979 + Identifier = "MarsAtmosphere", + Parent = transforms.Mars.Identifier, + Renderable = { + Type = "RenderableAtmosphere", + -- Atmosphere radius in Km + AtmosphereHeight = 3463.17495 - 3386.190, + PlanetRadius = 3386.190, + PlanetAverageGroundReflectance = 0.1, + GroundRadianceEmission = 0.37, + SunIntensity = 13.1, + MieScatteringExtinctionPropCoefficient = 0.23862, + Rayleigh = { + Coefficients = { + -- Wavelengths are given in 10^-9m + Wavelengths = { 680, 550, 440 }, + -- Reflection coefficients are given in km^-1 + Scattering = { 0.019918, 0.01357, 0.00575 } + -- In Rayleigh scattering, the coefficients of + -- absorption and scattering are the same. }, - -- Default - Mie = { - Coefficients = { - -- Reflection coefficients are given in km^-1 - Scattering = { 0.05361771, 0.05361771, 0.05361771 }, - -- Extinction coefficients are a fraction of the Scattering coefficients - Extinction = { 0.05361771 / 0.98979, 0.05361771 / 0.98979, 0.05361771 / 0.98979 } - }, - -- Mie Height scale (atmosphere thickness for constant density) in Km - H_M = 3.09526, - -- Mie Phase Function Value (G e [-1.0, 1.0]. - -- If G = 1.0, Mie phase function = Rayleigh Phase Function) - G = 0.85 - }, - Debug = { - PreCalculatedTextureScale = 1.0, - SaveCalculatedTextures = false - } + -- Thickness of atmosphere if its density were uniform, in Km + H_R = 10.43979 }, - GUI = { - Name = "Mars Atmosphere", - Path = "/Solar System/Planets/Mars", - Description = "Atmosphere of Mars" + -- Default + Mie = { + Coefficients = { + -- Reflection coefficients are given in km^-1 + Scattering = { 0.05361771, 0.05361771, 0.05361771 }, + -- Extinction coefficients are a fraction of the Scattering coefficients + Extinction = { 0.05361771 / 0.98979, 0.05361771 / 0.98979, 0.05361771 / 0.98979 } + }, + -- Mie Height scale (atmosphere thickness for constant density) in Km + H_M = 3.09526, + -- Mie Phase Function Value (G e [-1.0, 1.0]. + -- If G = 1.0, Mie phase function = Rayleigh Phase Function) + G = 0.85 + }, + Debug = { + PreCalculatedTextureScale = 1.0, + SaveCalculatedTextures = false } + }, + GUI = { + Name = "Mars Atmosphere", + Path = "/Solar System/Planets/Mars", + Focusable = false, + Description = "Atmosphere of Mars" + } } diff --git a/data/assets/scene/solarsystem/planets/mars/layers/colorlayers/mars_texture.asset b/data/assets/scene/solarsystem/planets/mars/layers/colorlayers/mars_texture.asset index 70c4d29acf..90ed5207d0 100644 --- a/data/assets/scene/solarsystem/planets/mars/layers/colorlayers/mars_texture.asset +++ b/data/assets/scene/solarsystem/planets/mars/layers/colorlayers/mars_texture.asset @@ -16,8 +16,7 @@ local Layer = { Enabled = asset.enabled, ZIndex = 5, FilePath = texturesPath .. "mars.png", - Description = "Default jpg texture for Mars", - CacheSettings = { Enabled = false } + Description = "Default jpg texture for Mars" } diff --git a/data/assets/scene/solarsystem/planets/mars/layers/colorlayers/moc_wa_color_newyork.asset b/data/assets/scene/solarsystem/planets/mars/layers/colorlayers/moc_wa_color_newyork.asset index b5354c64da..5a378193eb 100644 --- a/data/assets/scene/solarsystem/planets/mars/layers/colorlayers/moc_wa_color_newyork.asset +++ b/data/assets/scene/solarsystem/planets/mars/layers/colorlayers/moc_wa_color_newyork.asset @@ -12,9 +12,9 @@ local Layer = { Gamma = 1.6, Multiplier = 1.07 }, - Description = [[This map is an AMNH version of the global mossaic produced by the - Mars Global Surveyor Wide Angle Camera. This version has color added and the - shadows subdued based on the MOLA DTM. Data Reference: + Description = [[This map is an AMNH version of the global mosaic produced by the Mars + Global Surveyor Wide Angle Camera. This version has color added and the shadows + subdued based on the MOLA DTM. Data Reference: https://www.jpl.nasa.gov/spaceimages/details.php?id=PIA03467]] } diff --git a/data/assets/scene/solarsystem/planets/mars/layers/colorlayers/moc_wa_color_sweden.asset b/data/assets/scene/solarsystem/planets/mars/layers/colorlayers/moc_wa_color_sweden.asset index ec2c0fa09b..3809e6d6e1 100644 --- a/data/assets/scene/solarsystem/planets/mars/layers/colorlayers/moc_wa_color_sweden.asset +++ b/data/assets/scene/solarsystem/planets/mars/layers/colorlayers/moc_wa_color_sweden.asset @@ -12,9 +12,9 @@ local Layer = { Gamma = 1.6, Multiplier = 1.07 }, - Description = [[This map is an AMNH version of the global mossaic produced by the - Mars Global Surveyor Wide Angle Camera. This version has color added and the - shadows subdued based on the MOLA DTM. Data Reference: + Description = [[This map is an AMNH version of the global mosaic produced by the Mars + Global Surveyor Wide Angle Camera. This version has color added and the shadows + subdued based on the MOLA DTM. Data Reference: https://www.jpl.nasa.gov/spaceimages/details.php?id=PIA03467]] } diff --git a/data/assets/scene/solarsystem/planets/mars/layers/colorlayers/moc_wa_color_utah.asset b/data/assets/scene/solarsystem/planets/mars/layers/colorlayers/moc_wa_color_utah.asset index 2e37262615..04254c5af0 100644 --- a/data/assets/scene/solarsystem/planets/mars/layers/colorlayers/moc_wa_color_utah.asset +++ b/data/assets/scene/solarsystem/planets/mars/layers/colorlayers/moc_wa_color_utah.asset @@ -12,9 +12,9 @@ local Layer = { Gamma = 1.6, Multiplier = 1.07 }, - Description = [[This map is an AMNH version of the global mossaic produced by the - Mars Global Surveyor Wide Angle Camera. This version has color added and the - shadows subdued based on the MOLA DTM. Data Reference: + Description = [[This map is an AMNH version of the global mosaic produced by the Mars + Global Surveyor Wide Angle Camera. This version has color added and the shadows + subdued based on the MOLA DTM. Data Reference: https://www.jpl.nasa.gov/spaceimages/details.php?id=PIA03467]] } diff --git a/data/assets/scene/solarsystem/planets/mars/mars.asset b/data/assets/scene/solarsystem/planets/mars/mars.asset index f6b0ecf0e9..944eff00ee 100644 --- a/data/assets/scene/solarsystem/planets/mars/mars.asset +++ b/data/assets/scene/solarsystem/planets/mars/mars.asset @@ -81,6 +81,7 @@ local MarsLabel = { GUI = { Name = "Mars Label", Path = "/Solar System/Planets/Mars", + Focusable = false, Description = "Main label for Mars" } } diff --git a/data/assets/scene/solarsystem/planets/mars/moons/deimos.asset b/data/assets/scene/solarsystem/planets/mars/moons/deimos.asset index e35ac1c93d..9c19dbe128 100644 --- a/data/assets/scene/solarsystem/planets/mars/moons/deimos.asset +++ b/data/assets/scene/solarsystem/planets/mars/moons/deimos.asset @@ -68,6 +68,7 @@ local DeimosTrail = { GUI = { Name = "Deimos Trail", Path = "/Solar System/Planets/Mars/Moons/Deimos", + Focusable = false, Description = "Trail for Deimos" } } @@ -93,6 +94,7 @@ local DeimosLabel = { GUI = { Name = "Deimos Label", Path = "/Solar System/Planets/Mars/Moons/Deimos", + Focusable = false, Description = "Label for Mars' moon Deimos" } } diff --git a/data/assets/scene/solarsystem/planets/mars/moons/phobos.asset b/data/assets/scene/solarsystem/planets/mars/moons/phobos.asset index 8babafe4ea..e5caa8676b 100644 --- a/data/assets/scene/solarsystem/planets/mars/moons/phobos.asset +++ b/data/assets/scene/solarsystem/planets/mars/moons/phobos.asset @@ -68,6 +68,7 @@ local PhobosTrail = { GUI = { Name = "Phobos Trail", Path = "/Solar System/Planets/Mars/Moons/Phobos", + Focusable = false, Description = "Trail for Phobos" } } @@ -93,6 +94,7 @@ local PhobosLabel = { GUI = { Name = "Phobos Label", Path = "/Solar System/Planets/Mars/Moons/Phobos", + Focusable = false, Description = "Label for Mars' moon Phobos" } } diff --git a/data/assets/scene/solarsystem/planets/mars/trail.asset b/data/assets/scene/solarsystem/planets/mars/trail.asset index 1a602c1dcb..db1001d11e 100644 --- a/data/assets/scene/solarsystem/planets/mars/trail.asset +++ b/data/assets/scene/solarsystem/planets/mars/trail.asset @@ -21,6 +21,7 @@ local MarsTrail = { GUI = { Name = "Mars Trail", Path = "/Solar System/Planets/Mars", + Focusable = false, Description = "Trail of Mars as observed by the Sun" } } diff --git a/data/assets/scene/solarsystem/planets/mars/trail_barycenter.asset b/data/assets/scene/solarsystem/planets/mars/trail_barycenter.asset index c997945b12..ba704fdb4c 100644 --- a/data/assets/scene/solarsystem/planets/mars/trail_barycenter.asset +++ b/data/assets/scene/solarsystem/planets/mars/trail_barycenter.asset @@ -22,6 +22,7 @@ local MarsBarycenterTrail = { GUI = { Name = "Mars Barycenter Trail", Path = "/Solar System/Planets/Mars", + Focusable = false, Description = "Trail of Mars' Barycenter as observed by the Sun" } } diff --git a/data/assets/scene/solarsystem/planets/mars/trail_earth.asset b/data/assets/scene/solarsystem/planets/mars/trail_earth.asset index be2f3923e3..28001301c7 100644 --- a/data/assets/scene/solarsystem/planets/mars/trail_earth.asset +++ b/data/assets/scene/solarsystem/planets/mars/trail_earth.asset @@ -22,6 +22,7 @@ local MarsTrailEarth = { GUI = { Name = "Mars trail from Earth", Path = "/Solar System/Planets/Mars", + Focusable = false, Description = "Trail of Mars as observed by the Earth" } } diff --git a/data/assets/scene/solarsystem/planets/mars/transforms.asset b/data/assets/scene/solarsystem/planets/mars/transforms.asset index 8af3239f34..7e0fd4661a 100644 --- a/data/assets/scene/solarsystem/planets/mars/transforms.asset +++ b/data/assets/scene/solarsystem/planets/mars/transforms.asset @@ -16,6 +16,7 @@ local MarsBarycenter = { GUI = { Name = "Mars Barycenter", Path = "/Solar System/Planets/Mars", + Focusable = false, Hidden = true } } diff --git a/data/assets/scene/solarsystem/planets/mercury/layers/colorlayers/alsimap_02122015.asset b/data/assets/scene/solarsystem/planets/mercury/layers/colorlayers/alsimap_02122015.asset index 67c9e0c788..50514877ea 100644 --- a/data/assets/scene/solarsystem/planets/mercury/layers/colorlayers/alsimap_02122015.asset +++ b/data/assets/scene/solarsystem/planets/mercury/layers/colorlayers/alsimap_02122015.asset @@ -16,8 +16,7 @@ local Layer = { Enabled = asset.enabled, ZIndex = 100, FilePath = texturesPath .. "alsimap_02122015.png", - BlendMode = "Multiply", - CacheSettings = { Enabled = false } + BlendMode = "Multiply" } diff --git a/data/assets/scene/solarsystem/planets/mercury/layers/colorlayers/casimap_02122015.asset b/data/assets/scene/solarsystem/planets/mercury/layers/colorlayers/casimap_02122015.asset index 89ffa9f6e1..fee20dd587 100644 --- a/data/assets/scene/solarsystem/planets/mercury/layers/colorlayers/casimap_02122015.asset +++ b/data/assets/scene/solarsystem/planets/mercury/layers/colorlayers/casimap_02122015.asset @@ -16,8 +16,7 @@ local Layer = { Enabled = asset.enabled, ZIndex = 100, FilePath = texturesPath .. "casimap_02122015.png", - BlendMode = "Multiply", - CacheSettings = { Enabled = false } + BlendMode = "Multiply" } diff --git a/data/assets/scene/solarsystem/planets/mercury/layers/colorlayers/fesimap_02122015.asset b/data/assets/scene/solarsystem/planets/mercury/layers/colorlayers/fesimap_02122015.asset index 5dff0edc23..6f4647c0c5 100644 --- a/data/assets/scene/solarsystem/planets/mercury/layers/colorlayers/fesimap_02122015.asset +++ b/data/assets/scene/solarsystem/planets/mercury/layers/colorlayers/fesimap_02122015.asset @@ -16,8 +16,7 @@ local Layer = { Enabled = asset.enabled, ZIndex = 100, FilePath = texturesPath .. "fesimap_02122015.png", - BlendMode = "Multiply", - CacheSettings = { Enabled = false } + BlendMode = "Multiply" } diff --git a/data/assets/scene/solarsystem/planets/mercury/layers/colorlayers/mercury_texture.asset b/data/assets/scene/solarsystem/planets/mercury/layers/colorlayers/mercury_texture.asset index 7a8a724054..7e9613b655 100644 --- a/data/assets/scene/solarsystem/planets/mercury/layers/colorlayers/mercury_texture.asset +++ b/data/assets/scene/solarsystem/planets/mercury/layers/colorlayers/mercury_texture.asset @@ -17,8 +17,7 @@ local Layer = { ZIndex = 5, Description = [[The Map Projected Basemap RDR (BDR) data set consists of a global monochrome map of reflectance at a resolution of 256 pixels per degree (~166 m/p). - This is an offline version with lower resoution than the Messenger BDR layer.]], - CacheSettings = { Enabled = false } + This is an offline version with lower resoution than the Messenger BDR layer.]] } diff --git a/data/assets/scene/solarsystem/planets/mercury/layers/colorlayers/mgsimap_02122015.asset b/data/assets/scene/solarsystem/planets/mercury/layers/colorlayers/mgsimap_02122015.asset index 8bc88276ed..d895ad7f64 100644 --- a/data/assets/scene/solarsystem/planets/mercury/layers/colorlayers/mgsimap_02122015.asset +++ b/data/assets/scene/solarsystem/planets/mercury/layers/colorlayers/mgsimap_02122015.asset @@ -20,8 +20,7 @@ local Layer = { Gamma = 1.33, Multiplier = 1.15 }, - BlendMode = "Multiply", - CacheSettings = { Enabled = false } + BlendMode = "Multiply" } diff --git a/data/assets/scene/solarsystem/planets/mercury/layers/colorlayers/ssimap_02122015.asset b/data/assets/scene/solarsystem/planets/mercury/layers/colorlayers/ssimap_02122015.asset index 6973d2e05b..16d194176d 100644 --- a/data/assets/scene/solarsystem/planets/mercury/layers/colorlayers/ssimap_02122015.asset +++ b/data/assets/scene/solarsystem/planets/mercury/layers/colorlayers/ssimap_02122015.asset @@ -16,8 +16,7 @@ local Layer = { Enabled = asset.enabled, ZIndex = 100, FilePath = texturesPath .. "ssimap_02122015.png", - BlendMode = "Multiply", - CacheSettings = { Enabled = false } + BlendMode = "Multiply" } diff --git a/data/assets/scene/solarsystem/planets/mercury/mercury.asset b/data/assets/scene/solarsystem/planets/mercury/mercury.asset index 871df88f60..ad9a510cd6 100644 --- a/data/assets/scene/solarsystem/planets/mercury/mercury.asset +++ b/data/assets/scene/solarsystem/planets/mercury/mercury.asset @@ -64,13 +64,14 @@ local MercuryLabel = { BlendMode = "Additive", EnableFading = true, FadeUnit = "au", - FadeDistances = { 1.5, 20.0 }, + FadeDistances = { 0.75, 20.0 }, FadeWidths = { 1.0, 30.0 } }, Tag = { "solarsystem_labels" }, GUI = { Name = "Mercury Label", - Path = "/Solar System/Planets/Mercury" + Path = "/Solar System/Planets/Mercury", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/mercury/trail.asset b/data/assets/scene/solarsystem/planets/mercury/trail.asset index 6f24cac77f..f773c9ecbf 100644 --- a/data/assets/scene/solarsystem/planets/mercury/trail.asset +++ b/data/assets/scene/solarsystem/planets/mercury/trail.asset @@ -21,6 +21,7 @@ local MercuryTrail = { GUI = { Name = "Mercury Trail", Path = "/Solar System/Planets/Mercury", + Focusable = false, Description = "Trail of Mercury as observed by the Sun" } } diff --git a/data/assets/scene/solarsystem/planets/mercury/trail_barycenter.asset b/data/assets/scene/solarsystem/planets/mercury/trail_barycenter.asset index b7001285b4..f4ec2a9eea 100644 --- a/data/assets/scene/solarsystem/planets/mercury/trail_barycenter.asset +++ b/data/assets/scene/solarsystem/planets/mercury/trail_barycenter.asset @@ -22,6 +22,7 @@ local MercuryBarycenterTrail = { GUI = { Name = "Mercury Barycenter Trail", Path = "/Solar System/Planets/Mercury", + Focusable = false, Description = "Barycenter Trail of Mercury as observed by the Sun" } } diff --git a/data/assets/scene/solarsystem/planets/mercury/trail_earth.asset b/data/assets/scene/solarsystem/planets/mercury/trail_earth.asset index 97ed2e70d5..123d801a49 100644 --- a/data/assets/scene/solarsystem/planets/mercury/trail_earth.asset +++ b/data/assets/scene/solarsystem/planets/mercury/trail_earth.asset @@ -23,6 +23,7 @@ local MercuryTrailEarth = { GUI = { Name = "Mercury trail from Earth", Path = "/Solar System/Planets/Mercury", + Focusable = false, Description = "Trail of Mercury as observed by the Earth" } } diff --git a/data/assets/scene/solarsystem/planets/mercury/transforms.asset b/data/assets/scene/solarsystem/planets/mercury/transforms.asset index 30116f18e3..f6f70aebde 100644 --- a/data/assets/scene/solarsystem/planets/mercury/transforms.asset +++ b/data/assets/scene/solarsystem/planets/mercury/transforms.asset @@ -16,6 +16,7 @@ local MercuryBarycenter = { GUI = { Name = "Mercury Barycenter", Path = "/Solar System/Planets/Mercury", + Focusable = false, Hidden = true } } diff --git a/data/assets/scene/solarsystem/planets/neptune/inner_moons.asset b/data/assets/scene/solarsystem/planets/neptune/inner_moons.asset index 6ce4c2c2df..1c97a09f65 100644 --- a/data/assets/scene/solarsystem/planets/neptune/inner_moons.asset +++ b/data/assets/scene/solarsystem/planets/neptune/inner_moons.asset @@ -55,7 +55,8 @@ local NaiadTrail = { }, GUI = { Name = "Naiad Trail", - Path = "/Solar System/Planets/Neptune/Minor Moons/Inner Moons/Naiad" + Path = "/Solar System/Planets/Neptune/Minor Moons/Inner Moons/Naiad", + Focusable = false } } @@ -80,6 +81,7 @@ local NaiadLabel = { GUI = { Name = "Naiad Label", Path = "/Solar System/Planets/Neptune/Minor Moons/Inner Moons/Naiad", + Focusable = false, Description = "Label for Neptune's moon Naiad (Inner Moons)" } } @@ -135,7 +137,8 @@ local ThalassaTrail = { }, GUI = { Name = "Thalassa Trail", - Path = "/Solar System/Planets/Neptune/Minor Moons/Inner Moons/Thalassa" + Path = "/Solar System/Planets/Neptune/Minor Moons/Inner Moons/Thalassa", + Focusable = false } } @@ -160,6 +163,7 @@ local ThalassaLabel = { GUI = { Name = "Thalassa Label", Path = "/Solar System/Planets/Neptune/Minor Moons/Inner Moons/Thalassa", + Focusable = false, Description = "Label for Neptune's moon Thalassa (Inner Moons)" } } @@ -215,7 +219,8 @@ local DespinaTrail = { }, GUI = { Name = "Despina Trail", - Path = "/Solar System/Planets/Neptune/Minor Moons/Inner Moons/Despina" + Path = "/Solar System/Planets/Neptune/Minor Moons/Inner Moons/Despina", + Focusable = false } } @@ -240,6 +245,7 @@ local DespinaLabel = { GUI = { Name = "Despina Label", Path = "/Solar System/Planets/Neptune/Minor Moons/Inner Moons/Despina", + Focusable = false, Description = "Label for Neptune's moon Despina (Inner Moons)" } } @@ -295,7 +301,8 @@ local GalateaTrail = { }, GUI = { Name = "Galatea Trail", - Path = "/Solar System/Planets/Neptune/Minor Moons/Inner Moons/Galatea" + Path = "/Solar System/Planets/Neptune/Minor Moons/Inner Moons/Galatea", + Focusable = false } } @@ -320,6 +327,7 @@ local GalateaLabel = { GUI = { Name = "Galatea Label", Path = "/Solar System/Planets/Neptune/Minor Moons/Inner Moons/Galatea", + Focusable = false, Description = "Label for Neptune's moon Galatea (Inner Moons)" } } @@ -375,7 +383,8 @@ local LarissaTrail = { }, GUI = { Name = "Larissa Trail", - Path = "/Solar System/Planets/Neptune/Minor Moons/Inner Moons/Larissa" + Path = "/Solar System/Planets/Neptune/Minor Moons/Inner Moons/Larissa", + Focusable = false } } @@ -400,6 +409,7 @@ local LarissaLabel = { GUI = { Name = "Larissa Label", Path = "/Solar System/Planets/Neptune/Minor Moons/Inner Moons/Larissa", + Focusable = false, Description = "Label for Neptune's moon Larissa (Inner Moons)" } } @@ -455,7 +465,8 @@ local HippocampTrail = { }, GUI = { Name = "Hippocamp Trail", - Path = "/Solar System/Planets/Neptune/Minor Moons/Inner Moons/Hippocamp" + Path = "/Solar System/Planets/Neptune/Minor Moons/Inner Moons/Hippocamp", + Focusable = false } } @@ -480,6 +491,7 @@ local HippocampLabel = { GUI = { Name = "Hippocamp Label", Path = "/Solar System/Planets/Neptune/Minor Moons/Inner Moons/Hippocamp", + Focusable = false, Description = "Label for Neptune's moon Hippocamp (Inner Moons)" } } @@ -535,7 +547,8 @@ local ProteusTrail = { }, GUI = { Name = "Proteus Trail", - Path = "/Solar System/Planets/Neptune/Minor Moons/Inner Moons/Proteus" + Path = "/Solar System/Planets/Neptune/Minor Moons/Inner Moons/Proteus", + Focusable = false } } @@ -560,6 +573,7 @@ local ProteusLabel = { GUI = { Name = "Proteus Label", Path = "/Solar System/Planets/Neptune/Minor Moons/Inner Moons/Proteus", + Focusable = false, Description = "Label for Neptune's moon Proteus (Inner Moons)" } } diff --git a/data/assets/scene/solarsystem/planets/neptune/irregular_moons.asset b/data/assets/scene/solarsystem/planets/neptune/irregular_moons.asset index 0f17f84ff2..fa7fd20bc0 100644 --- a/data/assets/scene/solarsystem/planets/neptune/irregular_moons.asset +++ b/data/assets/scene/solarsystem/planets/neptune/irregular_moons.asset @@ -55,7 +55,8 @@ local HalimedeTrail = { }, GUI = { Name = "Halimede Trail", - Path = "/Solar System/Planets/Neptune/Minor Moons/Irregular Prograde Moons/Halimede" + Path = "/Solar System/Planets/Neptune/Minor Moons/Irregular Prograde Moons/Halimede", + Focusable = false } } @@ -80,6 +81,7 @@ local HalimedeLabel = { GUI = { Name = "Halimede Label", Path = "/Solar System/Planets/Neptune/Minor Moons/Irregular Prograde Moons/Halimede", + Focusable = false, Description = "Label for Neptune's moon Halimede (Irregular Prograde Moons)" } } @@ -135,7 +137,8 @@ local PsamatheTrail = { }, GUI = { Name = "Psamathe Trail", - Path = "/Solar System/Planets/Neptune/Minor Moons/Irregular Prograde Moons/Psamathe" + Path = "/Solar System/Planets/Neptune/Minor Moons/Irregular Prograde Moons/Psamathe", + Focusable = false } } @@ -160,6 +163,7 @@ local PsamatheLabel = { GUI = { Name = "Psamathe Label", Path = "/Solar System/Planets/Neptune/Minor Moons/Irregular Prograde Moons/Psamathe", + Focusable = false, Description = "Label for Neptune's moon Psamathe (Irregular Prograde Moons)" } } @@ -215,7 +219,8 @@ local SaoTrail = { }, GUI = { Name = "Sao Trail", - Path = "/Solar System/Planets/Neptune/Minor Moons/Irregular Prograde Moons/Sao" + Path = "/Solar System/Planets/Neptune/Minor Moons/Irregular Prograde Moons/Sao", + Focusable = false } } @@ -240,6 +245,7 @@ local SaoLabel = { GUI = { Name = "Sao Label", Path = "/Solar System/Planets/Neptune/Minor Moons/Irregular Prograde Moons/Sao", + Focusable = false, Description = "Label for Neptune's moon Sao (Irregular Prograde Moons)" } } @@ -295,7 +301,8 @@ local LaomedeiaTrail = { }, GUI = { Name = "Laomedeia Trail", - Path = "/Solar System/Planets/Neptune/Minor Moons/Irregular Prograde Moons/Laomedeia" + Path = "/Solar System/Planets/Neptune/Minor Moons/Irregular Prograde Moons/Laomedeia", + Focusable = false } } @@ -320,6 +327,7 @@ local LaomedeiaLabel = { GUI = { Name = "Laomedeia Label", Path = "/Solar System/Planets/Neptune/Minor Moons/Irregular Prograde Moons/Laomedeia", + Focusable = false, Description = "Label for Neptune's moon Laomedeia (Irregular Prograde Moons)" } } @@ -375,7 +383,8 @@ local NesoTrail = { }, GUI = { Name = "Neso Trail", - Path = "/Solar System/Planets/Neptune/Minor Moons/Irregular Prograde Moons/Neso" + Path = "/Solar System/Planets/Neptune/Minor Moons/Irregular Prograde Moons/Neso", + Focusable = false } } @@ -400,6 +409,7 @@ local NesoLabel = { GUI = { Name = "Neso Label", Path = "/Solar System/Planets/Neptune/Minor Moons/Irregular Prograde Moons/Neso", + Focusable = false, Description = "Label for Neptune's moon Neso (Irregular Prograde Moons)" } } diff --git a/data/assets/scene/solarsystem/planets/neptune/layers/colorlayers/neptune_texture.asset b/data/assets/scene/solarsystem/planets/neptune/layers/colorlayers/neptune_texture.asset index f94543ed00..0d3442b6b8 100644 --- a/data/assets/scene/solarsystem/planets/neptune/layers/colorlayers/neptune_texture.asset +++ b/data/assets/scene/solarsystem/planets/neptune/layers/colorlayers/neptune_texture.asset @@ -14,8 +14,7 @@ local Layer = { Identifier = "Texture", FilePath = texturesPath .. "neptune.jpg", Enabled = asset.enabled, - ZIndex = 5, - CacheSettings = { Enabled = false } + ZIndex = 5 } diff --git a/data/assets/scene/solarsystem/planets/neptune/nereid/nereid.asset b/data/assets/scene/solarsystem/planets/neptune/nereid/nereid.asset index 7db4b2e752..d14bd6671f 100644 --- a/data/assets/scene/solarsystem/planets/neptune/nereid/nereid.asset +++ b/data/assets/scene/solarsystem/planets/neptune/nereid/nereid.asset @@ -54,7 +54,8 @@ local NereidTrail = { }, GUI = { Name = "Nereid Trail", - Path = "/Solar System/Planets/Neptune/Major Moons/Nereid" + Path = "/Solar System/Planets/Neptune/Major Moons/Nereid", + Focusable = false } } @@ -79,6 +80,7 @@ local NereidLabel = { GUI = { Name = "Nereid Label", Path = "/Solar System/Planets/Neptune/Major Moons/Nereid", + Focusable = false, Description = "Label for Neptune's moon Nereid" } } diff --git a/data/assets/scene/solarsystem/planets/neptune/trail.asset b/data/assets/scene/solarsystem/planets/neptune/trail.asset index 80dea527af..e2ee211a0e 100644 --- a/data/assets/scene/solarsystem/planets/neptune/trail.asset +++ b/data/assets/scene/solarsystem/planets/neptune/trail.asset @@ -21,6 +21,7 @@ local NeptuneTrail = { GUI = { Name = "Neptune Trail", Path = "/Solar System/Planets/Neptune", + Focusable = false, Description = "Trail of Neptune as observed by the Sun" } } diff --git a/data/assets/scene/solarsystem/planets/neptune/trail_barycenter.asset b/data/assets/scene/solarsystem/planets/neptune/trail_barycenter.asset index 1627018a52..9af71b3d6b 100644 --- a/data/assets/scene/solarsystem/planets/neptune/trail_barycenter.asset +++ b/data/assets/scene/solarsystem/planets/neptune/trail_barycenter.asset @@ -22,6 +22,7 @@ local NeptuneBarycenterTrail = { GUI = { Name = "Neptune Barycenter Trail", Path = "/Solar System/Planets/Neptune", + Focusable = false, Description = "BarycenterTrail of Neptune as observed by the Sun" } } diff --git a/data/assets/scene/solarsystem/planets/neptune/trail_earth.asset b/data/assets/scene/solarsystem/planets/neptune/trail_earth.asset index 7f22e97c3f..6f98d3434d 100644 --- a/data/assets/scene/solarsystem/planets/neptune/trail_earth.asset +++ b/data/assets/scene/solarsystem/planets/neptune/trail_earth.asset @@ -23,6 +23,7 @@ local NeptuneTrailEarth = { GUI = { Name = "Neptune trail from Earth", Path = "/Solar System/Planets/Neptune", + Focusable = false, Description = "Trail of Neptune as observed by the Earth" } } diff --git a/data/assets/scene/solarsystem/planets/neptune/transforms.asset b/data/assets/scene/solarsystem/planets/neptune/transforms.asset index 9022f1a8e1..509fdd3e88 100644 --- a/data/assets/scene/solarsystem/planets/neptune/transforms.asset +++ b/data/assets/scene/solarsystem/planets/neptune/transforms.asset @@ -16,6 +16,7 @@ local NeptuneBarycenter = { GUI = { Name = "Neptune Barycenter", Path = "/Solar System/Planets/Neptune", + Focusable = false, Hidden = true } } diff --git a/data/assets/scene/solarsystem/planets/neptune/triton/layers/colorlayers/triton_voyager2_clrmosaic_globalfill_600m.asset b/data/assets/scene/solarsystem/planets/neptune/triton/layers/colorlayers/triton_voyager2_clrmosaic_globalfill_600m.asset index 6873986135..902e9dd9d4 100644 --- a/data/assets/scene/solarsystem/planets/neptune/triton/layers/colorlayers/triton_voyager2_clrmosaic_globalfill_600m.asset +++ b/data/assets/scene/solarsystem/planets/neptune/triton/layers/colorlayers/triton_voyager2_clrmosaic_globalfill_600m.asset @@ -20,8 +20,7 @@ local Layer = { Triton. This map has a resolution of 1,970 feet (600 meters per pixel [m]). Color was synthesized by combining high-resolution images taken through orange, violet, and ultraviolet filters; these images were displayed as red, green, and blue images and - combined to create this color version (Smith et al., 1989).]], - CacheSettings = { Enabled = false } + combined to create this color version (Smith et al., 1989).]] } diff --git a/data/assets/scene/solarsystem/planets/neptune/triton/triton.asset b/data/assets/scene/solarsystem/planets/neptune/triton/triton.asset index f50ba6297a..9c39930ed7 100644 --- a/data/assets/scene/solarsystem/planets/neptune/triton/triton.asset +++ b/data/assets/scene/solarsystem/planets/neptune/triton/triton.asset @@ -59,7 +59,8 @@ local TritonTrail = { }, GUI = { Name = "Triton Trail", - Path = "/Solar System/Planets/Neptune/Major Moons/Triton" + Path = "/Solar System/Planets/Neptune/Major Moons/Triton", + Focusable = false } } @@ -84,6 +85,7 @@ local TritonLabel = { GUI = { Name = "Triton Label", Path = "/Solar System/Planets/Neptune/Major Moons/Triton", + Focusable = false, Description = "Label for Neptune's moon Triton" } } diff --git a/data/assets/scene/solarsystem/planets/saturn/dione/dione.asset b/data/assets/scene/solarsystem/planets/saturn/dione/dione.asset index 0dd8f2b2aa..9d61827976 100644 --- a/data/assets/scene/solarsystem/planets/saturn/dione/dione.asset +++ b/data/assets/scene/solarsystem/planets/saturn/dione/dione.asset @@ -71,6 +71,7 @@ local DioneLabel = { GUI = { Name = "Dione Label", Path = "/Solar System/Planets/Saturn/Major Moons/Dione", + Focusable = false, Description = "Label for Saturn's moon Dione" } } diff --git a/data/assets/scene/solarsystem/planets/saturn/dione/layers/colorlayers/dione_texture.asset b/data/assets/scene/solarsystem/planets/saturn/dione/layers/colorlayers/dione_texture.asset index eeb6e3a222..1fed4f3e05 100644 --- a/data/assets/scene/solarsystem/planets/saturn/dione/layers/colorlayers/dione_texture.asset +++ b/data/assets/scene/solarsystem/planets/saturn/dione/layers/colorlayers/dione_texture.asset @@ -14,8 +14,7 @@ local Layer = { Identifier = "Texture", FilePath = texturesPath .. "dione.jpg", Enabled = asset.enabled, - ZIndex = 5, - CacheSettings = { Enabled = false } + ZIndex = 5 } diff --git a/data/assets/scene/solarsystem/planets/saturn/dione/trail.asset b/data/assets/scene/solarsystem/planets/saturn/dione/trail.asset index 8e5fda0d3e..9de391ea92 100644 --- a/data/assets/scene/solarsystem/planets/saturn/dione/trail.asset +++ b/data/assets/scene/solarsystem/planets/saturn/dione/trail.asset @@ -18,10 +18,16 @@ local DioneTrail = { Period = 66.0 / 24.0, Resolution = 1000 }, - Tag = { "moonTrail_solarSystem", "moonTrail_giants", "moonTrail_saturn", "moonTrail_major_saturn" }, + Tag = { + "moonTrail_solarSystem", + "moonTrail_giants", + "moonTrail_saturn", + "moonTrail_major_saturn" + }, GUI = { Name = "Dione Trail", Path = "/Solar System/Planets/Saturn/Major Moons/Dione", + Focusable = false, Description = "Trail of Saturn's moon Dione as observed by Saturn" } } diff --git a/data/assets/scene/solarsystem/planets/saturn/enceladus/enceladus.asset b/data/assets/scene/solarsystem/planets/saturn/enceladus/enceladus.asset index b218e8066c..f18ca0255f 100644 --- a/data/assets/scene/solarsystem/planets/saturn/enceladus/enceladus.asset +++ b/data/assets/scene/solarsystem/planets/saturn/enceladus/enceladus.asset @@ -72,6 +72,7 @@ local EnceladusLabel = { GUI = { Name = "Enceladus Label", Path = "/Solar System/Planets/Saturn/Major Moons/Enceladus", + Focusable = false, Description = "Label for Saturn's moon Enceladus" } } diff --git a/data/assets/scene/solarsystem/planets/saturn/enceladus/layers/colorlayers/enceladus_texture.asset b/data/assets/scene/solarsystem/planets/saturn/enceladus/layers/colorlayers/enceladus_texture.asset index 6455680049..a4c76ec6bd 100644 --- a/data/assets/scene/solarsystem/planets/saturn/enceladus/layers/colorlayers/enceladus_texture.asset +++ b/data/assets/scene/solarsystem/planets/saturn/enceladus/layers/colorlayers/enceladus_texture.asset @@ -14,8 +14,7 @@ local Layer = { Identifier = "Texture", FilePath = texturesPath .. "enceladus.jpg", Enabled = asset.enabled, - ZIndex = 5, - CacheSettings = { Enabled = false } + ZIndex = 5 } diff --git a/data/assets/scene/solarsystem/planets/saturn/enceladus/trail.asset b/data/assets/scene/solarsystem/planets/saturn/enceladus/trail.asset index 9cfd1ceca5..2de6a518bc 100644 --- a/data/assets/scene/solarsystem/planets/saturn/enceladus/trail.asset +++ b/data/assets/scene/solarsystem/planets/saturn/enceladus/trail.asset @@ -18,10 +18,16 @@ local EnceladusTrail = { Period = 33.0 / 24.0, Resolution = 1000 }, - Tag = { "moonTrail_solarSystem", "moonTrail_giants", "moonTrail_saturn", "moonTrail_major_saturn" }, + Tag = { + "moonTrail_solarSystem", + "moonTrail_giants", + "moonTrail_saturn", + "moonTrail_major_saturn" + }, GUI = { Name = "Enceladus Trail", Path = "/Solar System/Planets/Saturn/Major Moons/Enceladus", + Focusable = false, Description = "Trail of Saturn's moon Enceladus as observed by Saturn" } } diff --git a/data/assets/scene/solarsystem/planets/saturn/hyperion/hyperion.asset b/data/assets/scene/solarsystem/planets/saturn/hyperion/hyperion.asset index e2915d5ea4..2b5c2059b6 100644 --- a/data/assets/scene/solarsystem/planets/saturn/hyperion/hyperion.asset +++ b/data/assets/scene/solarsystem/planets/saturn/hyperion/hyperion.asset @@ -69,6 +69,7 @@ local HyperionLabel = { GUI = { Name = "Hyperion Label", Path = "/Solar System/Planets/Saturn/Major Moons/Hyperion", + Focusable = false, Description = "Label for Saturn's moon Hyperion" } } diff --git a/data/assets/scene/solarsystem/planets/saturn/hyperion/trail.asset b/data/assets/scene/solarsystem/planets/saturn/hyperion/trail.asset index 29260a58e8..9d706dd09f 100644 --- a/data/assets/scene/solarsystem/planets/saturn/hyperion/trail.asset +++ b/data/assets/scene/solarsystem/planets/saturn/hyperion/trail.asset @@ -26,7 +26,8 @@ local HyperionTrail = { }, GUI = { Name = "Hyperion Trail", - Path = "/Solar System/Planets/Saturn/Major Moons/Hyperion" + Path = "/Solar System/Planets/Saturn/Major Moons/Hyperion", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/saturn/iapetus/iapetus.asset b/data/assets/scene/solarsystem/planets/saturn/iapetus/iapetus.asset index e9a51fc40a..967c642a0a 100644 --- a/data/assets/scene/solarsystem/planets/saturn/iapetus/iapetus.asset +++ b/data/assets/scene/solarsystem/planets/saturn/iapetus/iapetus.asset @@ -71,7 +71,8 @@ local IapetusLabel = { Tag = { "solarsystem_labels", "moon_labels", "major_moon_labels" }, GUI = { Name = "Iapetus Label", - Path = "/Solar System/Planets/Saturn/Major Moons/Iapetus" + Path = "/Solar System/Planets/Saturn/Major Moons/Iapetus", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/saturn/iapetus/layers/colorlayers/iapetus_texture.asset b/data/assets/scene/solarsystem/planets/saturn/iapetus/layers/colorlayers/iapetus_texture.asset index c553c60b49..4c3ca4f0c6 100644 --- a/data/assets/scene/solarsystem/planets/saturn/iapetus/layers/colorlayers/iapetus_texture.asset +++ b/data/assets/scene/solarsystem/planets/saturn/iapetus/layers/colorlayers/iapetus_texture.asset @@ -14,8 +14,7 @@ local layer = { Identifier = "Texture", FilePath = texturesPath .. "iapetus.jpg", Enabled = asset.enabled, - ZIndex = 5, - CacheSettings = { Enabled = false } + ZIndex = 5 } diff --git a/data/assets/scene/solarsystem/planets/saturn/iapetus/trail.asset b/data/assets/scene/solarsystem/planets/saturn/iapetus/trail.asset index 1ced8f0d38..c91b9a1b5e 100644 --- a/data/assets/scene/solarsystem/planets/saturn/iapetus/trail.asset +++ b/data/assets/scene/solarsystem/planets/saturn/iapetus/trail.asset @@ -18,10 +18,16 @@ local IapetusTrail = { Period = 79.0, Resolution = 1000 }, - Tag = { "moonTrail_solarSystem", "moonTrail_giants", "moonTrail_saturn", "moonTrail_major_saturn" }, + Tag = { + "moonTrail_solarSystem", + "moonTrail_giants", + "moonTrail_saturn", + "moonTrail_major_saturn" + }, GUI = { Name = "Iapetus Trail", Path = "/Solar System/Planets/Saturn/Major Moons/Iapetus", + Focusable = false, Description = "Trail of Saturn's moon Iapetus as observed by Saturn" } } diff --git a/data/assets/scene/solarsystem/planets/saturn/layers/colorlayers/saturn_texture.asset b/data/assets/scene/solarsystem/planets/saturn/layers/colorlayers/saturn_texture.asset index 0bbcb2835b..5f58d5e668 100644 --- a/data/assets/scene/solarsystem/planets/saturn/layers/colorlayers/saturn_texture.asset +++ b/data/assets/scene/solarsystem/planets/saturn/layers/colorlayers/saturn_texture.asset @@ -14,8 +14,7 @@ local Layer = { Identifier = "Texture", FilePath = texturesPath .. "saturn.jpg", Enabled = asset.enabled, - ZIndex = 5, - CacheSettings = { Enabled = false } + ZIndex = 5 } diff --git a/data/assets/scene/solarsystem/planets/saturn/mimas/layers/colorlayers/mimas_texture.asset b/data/assets/scene/solarsystem/planets/saturn/mimas/layers/colorlayers/mimas_texture.asset index 1ee305fe18..08fc6b045b 100644 --- a/data/assets/scene/solarsystem/planets/saturn/mimas/layers/colorlayers/mimas_texture.asset +++ b/data/assets/scene/solarsystem/planets/saturn/mimas/layers/colorlayers/mimas_texture.asset @@ -14,8 +14,7 @@ local Layer = { Identifier = "Texture", FilePath = texturesPath .. "mimas.jpg", Enabled = asset.enabled, - ZIndex = 5, - CacheSettings = { Enabled = false } + ZIndex = 5 } diff --git a/data/assets/scene/solarsystem/planets/saturn/mimas/mimas.asset b/data/assets/scene/solarsystem/planets/saturn/mimas/mimas.asset index 2f6c3ade12..0de3973ade 100644 --- a/data/assets/scene/solarsystem/planets/saturn/mimas/mimas.asset +++ b/data/assets/scene/solarsystem/planets/saturn/mimas/mimas.asset @@ -73,6 +73,7 @@ local MimasLabel = { GUI = { Name = "Mimas Label", Path = "/Solar System/Planets/Saturn/Major Moons/Mimas", + Focusable = false, Description = "Label for Saturn's moon Mimas" } } diff --git a/data/assets/scene/solarsystem/planets/saturn/mimas/trail.asset b/data/assets/scene/solarsystem/planets/saturn/mimas/trail.asset index bc58f63adf..c9f42b5218 100644 --- a/data/assets/scene/solarsystem/planets/saturn/mimas/trail.asset +++ b/data/assets/scene/solarsystem/planets/saturn/mimas/trail.asset @@ -18,10 +18,16 @@ local MimasTrail = { Period = 23.0 / 24.0, Resolution = 1000 }, - Tag = { "moonTrail_solarSystem", "moonTrail_giants", "moonTrail_saturn", "moonTrail_major_saturn" }, + Tag = { + "moonTrail_solarSystem", + "moonTrail_giants", + "moonTrail_saturn", + "moonTrail_major_saturn" + }, GUI = { Name = "Mimas Trail", Path = "/Solar System/Planets/Saturn/Major Moons/Mimas", + Focusable = false, Description = "Trail of Saturn's moon Mimas as observed by Saturn" } } diff --git a/data/assets/scene/solarsystem/planets/saturn/minor/gallic_group.asset b/data/assets/scene/solarsystem/planets/saturn/minor/gallic_group.asset index 3767e88daa..f6ffa416af 100644 --- a/data/assets/scene/solarsystem/planets/saturn/minor/gallic_group.asset +++ b/data/assets/scene/solarsystem/planets/saturn/minor/gallic_group.asset @@ -56,7 +56,8 @@ local AlbiorixTrail = { }, GUI = { Name = "Albiorix Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Gallic Group/Albiorix" + Path = "/Solar System/Planets/Saturn/Minor Moons/Gallic Group/Albiorix", + Focusable = false } } @@ -86,7 +87,8 @@ local AlbiorixLabel = { }, GUI = { Name = "Albiorix Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Gallic Group/Albiorix" + Path = "/Solar System/Planets/Saturn/Minor Moons/Gallic Group/Albiorix", + Focusable = false } } @@ -142,7 +144,8 @@ local BebhionnTrail = { }, GUI = { Name = "Bebhionn Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Gallic Group/Bebhionn" + Path = "/Solar System/Planets/Saturn/Minor Moons/Gallic Group/Bebhionn", + Focusable = false } } @@ -172,7 +175,8 @@ local BebhionnLabel = { }, GUI = { Name = "Bebhionn Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Gallic Group/Bebhionn" + Path = "/Solar System/Planets/Saturn/Minor Moons/Gallic Group/Bebhionn", + Focusable = false } } @@ -228,7 +232,8 @@ local ErriapusTrail = { }, GUI = { Name = "Erriapus Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Gallic Group/Erriapus" + Path = "/Solar System/Planets/Saturn/Minor Moons/Gallic Group/Erriapus", + Focusable = false } } @@ -258,7 +263,8 @@ local ErriapusLabel = { }, GUI = { Name = "Erriapus Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Gallic Group/Erriapus" + Path = "/Solar System/Planets/Saturn/Minor Moons/Gallic Group/Erriapus", + Focusable = false } } @@ -314,7 +320,8 @@ local TarvosTrail = { }, GUI = { Name = "Tarvos Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Gallic Group/Tarvos" + Path = "/Solar System/Planets/Saturn/Minor Moons/Gallic Group/Tarvos", + Focusable = false } } @@ -344,7 +351,8 @@ local TarvosLabel = { }, GUI = { Name = "Tarvos Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Gallic Group/Tarvos" + Path = "/Solar System/Planets/Saturn/Minor Moons/Gallic Group/Tarvos", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/saturn/minor/inuit_group.asset b/data/assets/scene/solarsystem/planets/saturn/minor/inuit_group.asset index 55403af79c..ad7c1f9481 100644 --- a/data/assets/scene/solarsystem/planets/saturn/minor/inuit_group.asset +++ b/data/assets/scene/solarsystem/planets/saturn/minor/inuit_group.asset @@ -56,7 +56,8 @@ local KiviuqTrail = { }, GUI = { Name = "Kiviuq Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/Kiviuq" + Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/Kiviuq", + Focusable = false } } @@ -86,7 +87,8 @@ local KiviuqLabel = { }, GUI = { Name = "Kiviuq Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/Kiviuq" + Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/Kiviuq", + Focusable = false } } @@ -142,7 +144,8 @@ local IjiraqTrail = { }, GUI = { Name = "Ijiraq Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/Ijiraq" + Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/Ijiraq", + Focusable = false } } @@ -172,7 +175,8 @@ local IjiraqLabel = { }, GUI = { Name = "Ijiraq Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/Ijiraq" + Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/Ijiraq", + Focusable = false } } @@ -228,7 +232,8 @@ local PaaliaqTrail = { }, GUI = { Name = "Paaliaq Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/Paaliaq" + Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/Paaliaq", + Focusable = false } } @@ -258,7 +263,8 @@ local PaaliaqLabel = { }, GUI = { Name = "Paaliaq Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/Paaliaq" + Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/Paaliaq", + Focusable = false } } @@ -314,7 +320,8 @@ local SiarnaqTrail = { }, GUI = { Name = "Cyllene Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/Cyllene" + Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/Cyllene", + Focusable = false } } @@ -344,7 +351,8 @@ local SiarnaqLabel = { }, GUI = { Name = "Siarnaq Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/Siarnaq" + Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/Siarnaq", + Focusable = false } } @@ -400,7 +408,8 @@ local TarqeqTrail = { }, GUI = { Name = "Tarqeq Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/Tarqeq" + Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/Tarqeq", + Focusable = false } } @@ -430,7 +439,8 @@ local TarqeqLabel = { }, GUI = { Name = "Tarqeq Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/Tarqeq" + Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/Tarqeq", + Focusable = false } } @@ -486,7 +496,8 @@ local S2004S29Trail = { }, GUI = { Name = "S/2004 S 29 Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/S2004S29" + Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/S2004S29", + Focusable = false } } @@ -516,7 +527,8 @@ local S2004S29Label = { }, GUI = { Name = "S/2004 S 29 Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/S2004S29" + Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/S2004S29", + Focusable = false } } @@ -572,7 +584,8 @@ local S2004S31Trail = { }, GUI = { Name = "S/2004 S 31 Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/S2004S31" + Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/S2004S31", + Focusable = false } } @@ -602,7 +615,8 @@ local S2004S31Label = { }, GUI = { Name = "S/2004 S 31 Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/S2004S31" + Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/S2004S31", + Focusable = false } } @@ -658,7 +672,8 @@ local S2019S01Trail = { }, GUI = { Name = "S/2019 S 01 Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/S2019S01" + Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/S2019S01", + Focusable = false } } @@ -688,7 +703,8 @@ local S2019S01Label = { }, GUI = { Name = "S/2019 S 01 Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/S2019S01" + Path = "/Solar System/Planets/Saturn/Minor Moons/Inuit Group/S2019S01", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/saturn/minor/norse_group.asset b/data/assets/scene/solarsystem/planets/saturn/minor/norse_group.asset index 9e0499b62f..effe289a12 100644 --- a/data/assets/scene/solarsystem/planets/saturn/minor/norse_group.asset +++ b/data/assets/scene/solarsystem/planets/saturn/minor/norse_group.asset @@ -57,7 +57,8 @@ local PhoebeTrail = { }, GUI = { Name = "Phoebe Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Phoebe" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Phoebe", + Focusable = false } } @@ -87,7 +88,8 @@ local PhoebeLabel = { }, GUI = { Name = "Phoebe Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Phoebe" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Phoebe", + Focusable = false } } @@ -143,7 +145,8 @@ local SkathiTrail = { }, GUI = { Name = "Skathi Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Skathi" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Skathi", + Focusable = false } } @@ -173,7 +176,8 @@ local SkathiLabel = { }, GUI = { Name = "Skathi Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Skathi" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Skathi", + Focusable = false } } @@ -229,7 +233,8 @@ local S2007S2Trail = { }, GUI = { Name = "S/2007 S 2 Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2007S2" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2007S2", + Focusable = false } } @@ -259,7 +264,8 @@ local S2007S2Label = { }, GUI = { Name = "S/2007 S 2 Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2007S2" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2007S2", + Focusable = false } } @@ -315,7 +321,8 @@ local SkollTrail = { }, GUI = { Name = "Skoll Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Skoll" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Skoll", + Focusable = false } } @@ -345,7 +352,8 @@ local SkollLabel = { }, GUI = { Name = "Skoll Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Skoll" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Skoll", + Focusable = false } } @@ -401,7 +409,8 @@ local S2004S13Trail = { }, GUI = { Name = "S/2004 S 13 Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S13" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S13", + Focusable = false } } @@ -431,7 +440,8 @@ local S2004S13Label = { }, GUI = { Name = "S/2004 S 13 Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S13" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S13", + Focusable = false } } @@ -487,7 +497,8 @@ local GreipTrail = { }, GUI = { Name = "Greip Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Greip" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Greip", + Focusable = false } } @@ -517,7 +528,8 @@ local GreipLabel = { }, GUI = { Name = "Greip Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Greip" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Greip", + Focusable = false } } @@ -573,7 +585,8 @@ local HyrrokkinTrail = { }, GUI = { Name = "Hyrrokkin Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Hyrrokkin" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Hyrrokkin", + Focusable = false } } @@ -603,7 +616,8 @@ local HyrrokkinLabel = { }, GUI = { Name = "Hyrrokkin Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Hyrrokkin" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Hyrrokkin", + Focusable = false } } @@ -659,7 +673,8 @@ local JarnsaxaTrail = { }, GUI = { Name = "Jarnsaxa Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Jarnsaxa" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Jarnsaxa", + Focusable = false } } @@ -689,7 +704,8 @@ local JarnsaxaLabel = { }, GUI = { Name = "Jarnsaxa Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Jarnsaxa" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Jarnsaxa", + Focusable = false } } @@ -745,7 +761,8 @@ local MundilfariTrail = { }, GUI = { Name = "Mundilfari Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Mundilfari" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Mundilfari", + Focusable = false } } @@ -775,7 +792,8 @@ local MundilfariLabel = { }, GUI = { Name = "Mundilfari Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Mundilfari" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Mundilfari", + Focusable = false } } @@ -831,7 +849,8 @@ local S2006S1Trail = { }, GUI = { Name = "S/2006 S 1 Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2006S1" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2006S1", + Focusable = false } } @@ -861,7 +880,8 @@ local S2006S1Label = { }, GUI = { Name = "S/2006 S 1 Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2006S1" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2006S1", + Focusable = false } } @@ -917,7 +937,8 @@ local S2004S17Trail = { }, GUI = { Name = "S/2004 S 17 Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S17" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S17", + Focusable = false } } @@ -947,7 +968,8 @@ local S2004S17Label = { }, GUI = { Name = "S/2004 S 17 Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S17" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S17", + Focusable = false } } @@ -1003,7 +1025,8 @@ local BergelmirTrail = { }, GUI = { Name = "Bergelmir Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Bergelmir" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Bergelmir", + Focusable = false } } @@ -1033,7 +1056,8 @@ local BergelmirLabel = { }, GUI = { Name = "Bergelmir Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Bergelmir" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Bergelmir", + Focusable = false } } @@ -1089,7 +1113,8 @@ local NarviTrail = { }, GUI = { Name = "Narvi Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Narvi" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Narvi", + Focusable = false } } @@ -1119,7 +1144,8 @@ local NarviLabel = { }, GUI = { Name = "Narvi Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Narvi" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Narvi", + Focusable = false } } @@ -1175,7 +1201,8 @@ local SuttungrTrail = { }, GUI = { Name = "Suttungr Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Suttungr" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Suttungr", + Focusable = false } } @@ -1205,7 +1232,8 @@ local SuttungrLabel = { }, GUI = { Name = "Suttungr Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Suttungr" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Suttungr", + Focusable = false } } @@ -1261,7 +1289,8 @@ local HatiTrail = { }, GUI = { Name = "Hati Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Hati" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Hati", + Focusable = false } } @@ -1291,7 +1320,8 @@ local HatiLabel = { }, GUI = { Name = "Hati Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Hati" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Hati", + Focusable = false } } @@ -1347,7 +1377,8 @@ local S2004S12Trail = { }, GUI = { Name = "S/2004 S 12 Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S12" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S12", + Focusable = false } } @@ -1377,7 +1408,8 @@ local S2004S12Label = { }, GUI = { Name = "S/2004 S 12 Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S12" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S12", + Focusable = false } } @@ -1433,7 +1465,8 @@ local FarbautiTrail = { }, GUI = { Name = "Farbauti Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Farbauti" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Farbauti", + Focusable = false } } @@ -1463,7 +1496,8 @@ local FarbautiLabel = { }, GUI = { Name = "Farbauti Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Farbauti" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Farbauti", + Focusable = false } } @@ -1519,7 +1553,8 @@ local ThrymrTrail = { }, GUI = { Name = "Thrymr Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Thrymr" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Thrymr", + Focusable = false } } @@ -1549,7 +1584,8 @@ local ThrymrLabel = { }, GUI = { Name = "Thrymr Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Thrymr" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Thrymr", + Focusable = false } } @@ -1605,7 +1641,8 @@ local AegirTrail = { }, GUI = { Name = "Aegir Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Aegir" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Aegir", + Focusable = false } } @@ -1635,7 +1672,8 @@ local AegirLabel = { }, GUI = { Name = "Aegir Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Aegir" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Aegir", + Focusable = false } } @@ -1691,7 +1729,8 @@ local S2007S3Trail = { }, GUI = { Name = "S/2007 S 3 Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2007S3" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2007S3", + Focusable = false } } @@ -1721,7 +1760,8 @@ local S2007S3Label = { }, GUI = { Name = "S/2007 S 3 Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2007S3" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2007S3", + Focusable = false } } @@ -1777,7 +1817,8 @@ local BestlaTrail = { }, GUI = { Name = "Bestla Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Bestla" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Bestla", + Focusable = false } } @@ -1807,7 +1848,8 @@ local BestlaLabel = { }, GUI = { Name = "Bestla Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Bestla" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Bestla", + Focusable = false } } @@ -1863,7 +1905,8 @@ local S2004S7Trail = { }, GUI = { Name = "S/2004 S 7 Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S7" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S7", + Focusable = false } } @@ -1893,7 +1936,8 @@ local S2004S7Label = { }, GUI = { Name = "S/2004 S 7 Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S7" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S7", + Focusable = false } } @@ -1949,7 +1993,8 @@ local S2006S3Trail = { }, GUI = { Name = "S/2006 S 3 Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2006S3" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2006S3", + Focusable = false } } @@ -1979,7 +2024,8 @@ local S2006S3Label = { }, GUI = { Name = "S/2006 S 3 Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2006S3" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2006S3", + Focusable = false } } @@ -2035,7 +2081,8 @@ local FenrirTrail = { }, GUI = { Name = "Fenrir Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Fenrir" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Fenrir", + Focusable = false } } @@ -2065,7 +2112,8 @@ local FenrirLabel = { }, GUI = { Name = "Fenrir Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Fenrir" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Fenrir", + Focusable = false } } @@ -2121,7 +2169,8 @@ local SurturTrail = { }, GUI = { Name = "Surtur Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Surtur" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Surtur", + Focusable = false } } @@ -2151,7 +2200,8 @@ local SurturLabel = { }, GUI = { Name = "Surtur Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Surtur" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Surtur", + Focusable = false } } @@ -2207,7 +2257,8 @@ local KariTrail = { }, GUI = { Name = "Kari Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Kari" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Kari", + Focusable = false } } @@ -2237,7 +2288,8 @@ local KariLabel = { }, GUI = { Name = "Kari Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Kari" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Kari", + Focusable = false } } @@ -2293,7 +2345,8 @@ local YmirTrail = { }, GUI = { Name = "Ymir Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Ymir" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Ymir", + Focusable = false } } @@ -2323,7 +2376,8 @@ local YmirLabel = { }, GUI = { Name = "Ymir Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Ymir" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Ymir", + Focusable = false } } @@ -2379,7 +2433,8 @@ local LogeTrail = { }, GUI = { Name = "Loge Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Loge" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Loge", + Focusable = false } } @@ -2409,7 +2464,8 @@ local LogeLabel = { }, GUI = { Name = "Loge Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Loge" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Loge", + Focusable = false } } @@ -2465,7 +2521,8 @@ local FornjotTrail = { }, GUI = { Name = "Fornjot Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Fornjot" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Fornjot", + Focusable = false } } @@ -2495,7 +2552,8 @@ local FornjotLabel = { }, GUI = { Name = "Fornjot Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Fornjot" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Fornjot", + Focusable = false } } @@ -2551,7 +2609,8 @@ local SkadiTrail = { }, GUI = { Name = "Skadi Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Skadi" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Skadi", + Focusable = false } } @@ -2581,7 +2640,8 @@ local SkadiLabel = { }, GUI = { Name = "Skadi Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Skadi" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Skadi", + Focusable = false } } @@ -2637,7 +2697,8 @@ local GridrTrail = { }, GUI = { Name = "Gridr Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Gridr" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Gridr", + Focusable = false } } @@ -2667,7 +2728,8 @@ local GridrLabel = { }, GUI = { Name = "Gridr Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Gridr" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Gridr", + Focusable = false } } @@ -2723,7 +2785,8 @@ local AngrbodaTrail = { }, GUI = { Name = "Angrboda Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Angrboda" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Angrboda", + Focusable = false } } @@ -2753,7 +2816,8 @@ local AngrbodaLabel = { }, GUI = { Name = "Angrboda Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Angrboda" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Angrboda", + Focusable = false } } @@ -2809,7 +2873,8 @@ local SkrymirTrail = { }, GUI = { Name = "Skrymir Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Skrymir" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Skrymir", + Focusable = false } } @@ -2839,7 +2904,8 @@ local SkrymirLabel = { }, GUI = { Name = "Skrymir Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Skrymir" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Skrymir", + Focusable = false } } @@ -2895,7 +2961,8 @@ local GerdTrail = { }, GUI = { Name = "Gerd Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Gerd" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Gerd", + Focusable = false } } @@ -2925,7 +2992,8 @@ local GerdLabel = { }, GUI = { Name = "Gerd Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Gerd" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Gerd", + Focusable = false } } @@ -2981,7 +3049,8 @@ local S2004S26Trail = { }, GUI = { Name = "S/2004 S 26 Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S26" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S26", + Focusable = false } } @@ -3011,7 +3080,8 @@ local S2004S26Label = { }, GUI = { Name = "S/2004 S 26 Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S26" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S26", + Focusable = false } } @@ -3067,7 +3137,8 @@ local EggtherTrail = { }, GUI = { Name = "Eggther Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Eggther" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Eggther", + Focusable = false } } @@ -3097,7 +3168,8 @@ local EggtherLabel = { }, GUI = { Name = "Eggther Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Eggther" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Eggther", + Focusable = false } } @@ -3153,7 +3225,8 @@ local BeliTrail = { }, GUI = { Name = "Beli Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Beli" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Beli", + Focusable = false } } @@ -3183,7 +3256,8 @@ local BeliLabel = { }, GUI = { Name = "Beli Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Beli" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Beli", + Focusable = false } } @@ -3239,7 +3313,8 @@ local GunnlodTrail = { }, GUI = { Name = "Gunnlod Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Gunnlod" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Gunnlod", + Focusable = false } } @@ -3269,7 +3344,8 @@ local GunnlodLabel = { }, GUI = { Name = "Gunnlod Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Gunnlod" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Gunnlod", + Focusable = false } } @@ -3325,7 +3401,8 @@ local ThiazziTrail = { }, GUI = { Name = "Thiazzi Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Thiazzi" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Thiazzi", + Focusable = false } } @@ -3355,7 +3432,8 @@ local ThiazziLabel = { }, GUI = { Name = "Thiazzi Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Thiazzi" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Thiazzi", + Focusable = false } } @@ -3411,7 +3489,8 @@ local S2004S34Trail = { }, GUI = { Name = "S/2004 S 34 Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S34" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S34", + Focusable = false } } @@ -3441,7 +3520,8 @@ local S2004S34Label = { }, GUI = { Name = "S/2004 S 34 Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S34" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S34", + Focusable = false } } @@ -3497,7 +3577,8 @@ local AlvaldiTrail = { }, GUI = { Name = "Alvaldi Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Alvaldi" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Alvaldi", + Focusable = false } } @@ -3527,7 +3608,8 @@ local AlvaldiLabel = { }, GUI = { Name = "Alvaldi Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Alvaldi" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Alvaldi", + Focusable = false } } @@ -3583,7 +3665,8 @@ local GeirrodTrail = { }, GUI = { Name = "Geirrod Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Geirrod" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Geirrod", + Focusable = false } } @@ -3613,7 +3696,8 @@ local GeirrodLabel = { }, GUI = { Name = "Geirrod Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Geirrod" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/Geirrod", + Focusable = false } } @@ -3669,7 +3753,8 @@ local S2004S28Trail = { }, GUI = { Name = "S/2004 S 28 Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S28" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S28", + Focusable = false } } @@ -3699,7 +3784,8 @@ local S2004S28Label = { }, GUI = { Name = "S/2004 S 28 Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S28" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S28", + Focusable = false } } @@ -3755,7 +3841,8 @@ local S2004S21Trail = { }, GUI = { Name = "S/2004 S 21 Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S21" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S21", + Focusable = false } } @@ -3785,7 +3872,8 @@ local S2004S21Label = { }, GUI = { Name = "S/2004 S 21 Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S21" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S21", + Focusable = false } } @@ -3841,7 +3929,8 @@ local S2004S36Trail = { }, GUI = { Name = "S/2004 S 36 Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S36" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S36", + Focusable = false } } @@ -3871,7 +3960,8 @@ local S2004S36Label = { }, GUI = { Name = "S/2004 S 36 Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S36" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S36", + Focusable = false } } @@ -3927,7 +4017,8 @@ local S2004S37Trail = { }, GUI = { Name = "S/2004 S 37 Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S37" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S37", + Focusable = false } } @@ -3957,7 +4048,8 @@ local S2004S37Label = { }, GUI = { Name = "S/2004 S 37 Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S37" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S37", + Focusable = false } } @@ -4013,7 +4105,8 @@ local S2004S39Trail = { }, GUI = { Name = "S/2004 S 39 Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S39" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S39", + Focusable = false } } @@ -4043,7 +4136,8 @@ local S2004S39Label = { }, GUI = { Name = "S/2004 S 39 Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S39" + Path = "/Solar System/Planets/Saturn/Minor Moons/Norse Group/S2004S39", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/saturn/minor/other_group.asset b/data/assets/scene/solarsystem/planets/saturn/minor/other_group.asset index 6a10e65078..fa15db0741 100644 --- a/data/assets/scene/solarsystem/planets/saturn/minor/other_group.asset +++ b/data/assets/scene/solarsystem/planets/saturn/minor/other_group.asset @@ -58,7 +58,8 @@ local AegaeonTrail = { }, GUI = { Name = "Aegaeon Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Aegaeon" + Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Aegaeon", + Focusable = false } } @@ -88,7 +89,8 @@ local AegaeonLabel = { }, GUI = { Name = "Aegaeon Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Aegaeon" + Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Aegaeon", + Focusable = false } } @@ -144,7 +146,8 @@ local MethoneTrail = { }, GUI = { Name = "Methone Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Methone" + Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Methone", + Focusable = false } } @@ -174,7 +177,8 @@ local MethoneLabel = { }, GUI = { Name = "Methone Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Methone" + Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Methone", + Focusable = false } } @@ -230,7 +234,8 @@ local AntheTrail = { }, GUI = { Name = "Anthe Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Anthe" + Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Anthe", + Focusable = false } } @@ -260,7 +265,8 @@ local AntheLabel = { }, GUI = { Name = "Anthe Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Anthe" + Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Anthe", + Focusable = false } } @@ -316,7 +322,8 @@ local PalleneTrail = { }, GUI = { Name = "Pallene Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Pallene" + Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Pallene", + Focusable = false } } @@ -346,7 +353,8 @@ local PalleneLabel = { }, GUI = { Name = "Pallene Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Pallene" + Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Pallene", + Focusable = false } } @@ -402,7 +410,8 @@ local TelestoTrail = { }, GUI = { Name = "Telesto Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Telesto" + Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Telesto", + Focusable = false } } @@ -432,7 +441,8 @@ local TelestoLabel = { }, GUI = { Name = "Telesto Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Telesto" + Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Telesto", + Focusable = false } } @@ -488,7 +498,8 @@ local CalypsoTrail = { }, GUI = { Name = "Calypso Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Calypso" + Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Calypso", + Focusable = false } } @@ -518,7 +529,8 @@ local CalypsoLabel = { }, GUI = { Name = "Calypso Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Calypso" + Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Calypso", + Focusable = false } } @@ -574,7 +586,8 @@ local HeleneTrail = { }, GUI = { Name = "Helene Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Helene" + Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Helene", + Focusable = false } } @@ -604,7 +617,8 @@ local HeleneLabel = { }, GUI = { Name = "Helene Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Helene" + Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Helene", + Focusable = false } } @@ -660,7 +674,8 @@ local PolydeucesTrail = { }, GUI = { Name = "Polydeuces Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Polydeuces" + Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Polydeuces", + Focusable = false } } @@ -690,7 +705,8 @@ local PolydeucesLabel = { }, GUI = { Name = "Polydeuces Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Polydeuces" + Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/Polydeuces", + Focusable = false } } @@ -746,7 +762,8 @@ local S2004S24Trail = { }, GUI = { Name = "S/2004 S 24 Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/S2004S24" + Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/S2004S24", + Focusable = false } } @@ -776,7 +793,8 @@ local S2004S24Label = { }, GUI = { Name = "S/2004 S 24 Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/S2004S24" + Path = "/Solar System/Planets/Saturn/Minor Moons/Other Group/S2004S24", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/saturn/minor/shepherd_group.asset b/data/assets/scene/solarsystem/planets/saturn/minor/shepherd_group.asset index b371212420..41453d88d5 100644 --- a/data/assets/scene/solarsystem/planets/saturn/minor/shepherd_group.asset +++ b/data/assets/scene/solarsystem/planets/saturn/minor/shepherd_group.asset @@ -69,7 +69,8 @@ local PrometheusTrail = { }, GUI = { Name = "Prometheus Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Shepherd Moons/Prometheus" + Path = "/Solar System/Planets/Saturn/Minor Moons/Shepherd Moons/Prometheus", + Focusable = false } } @@ -99,7 +100,8 @@ local PrometheusLabel = { }, GUI = { Name = "Prometheus Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Shepherd Moons/Prometheus" + Path = "/Solar System/Planets/Saturn/Minor Moons/Shepherd Moons/Prometheus", + Focusable = false } } @@ -155,7 +157,8 @@ local PandoraTrail = { }, GUI = { Name = "Pandora Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Shepherd Moons/Pandora" + Path = "/Solar System/Planets/Saturn/Minor Moons/Shepherd Moons/Pandora", + Focusable = false } } @@ -185,7 +188,8 @@ local PandoraLabel = { }, GUI = { Name = "Pandora Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Shepherd Moons/Pandora" + Path = "/Solar System/Planets/Saturn/Minor Moons/Shepherd Moons/Pandora", + Focusable = false } } @@ -241,7 +245,8 @@ local AtlasTrail = { }, GUI = { Name = "Atlas Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Shepherd Moons/Atlas" + Path = "/Solar System/Planets/Saturn/Minor Moons/Shepherd Moons/Atlas", + Focusable = false } } @@ -271,7 +276,8 @@ local AtlasLabel = { }, GUI = { Name = "Atlas Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Shepherd Moons/Atlas" + Path = "/Solar System/Planets/Saturn/Minor Moons/Shepherd Moons/Atlas", + Focusable = false } } @@ -327,7 +333,8 @@ local JanusTrail = { }, GUI = { Name = "Janus Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Shepherd Moons/Janus" + Path = "/Solar System/Planets/Saturn/Minor Moons/Shepherd Moons/Janus", + Focusable = false } } @@ -357,7 +364,8 @@ local JanusLabel = { }, GUI = { Name = "Janus Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Shepherd Moons/Janus" + Path = "/Solar System/Planets/Saturn/Minor Moons/Shepherd Moons/Janus", + Focusable = false } } @@ -413,7 +421,8 @@ local EpimetheusTrail = { }, GUI = { Name = "Epimetheus Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Shepherd Moons/Epimetheus" + Path = "/Solar System/Planets/Saturn/Minor Moons/Shepherd Moons/Epimetheus", + Focusable = false } } @@ -443,7 +452,8 @@ local EpimetheusLabel = { }, GUI = { Name = "Epimetheus Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Shepherd Moons/Epimetheus" + Path = "/Solar System/Planets/Saturn/Minor Moons/Shepherd Moons/Epimetheus", + Focusable = false } } @@ -499,7 +509,8 @@ local DaphnisTrail = { }, GUI = { Name = "Daphnis Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Shepherd Moons/Daphnis" + Path = "/Solar System/Planets/Saturn/Minor Moons/Shepherd Moons/Daphnis", + Focusable = false } } @@ -529,7 +540,8 @@ local DaphnisLabel = { }, GUI = { Name = "Daphnis Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Shepherd Moons/Daphnis" + Path = "/Solar System/Planets/Saturn/Minor Moons/Shepherd Moons/Daphnis", + Focusable = false } } @@ -585,7 +597,8 @@ local PanTrail = { }, GUI = { Name = "Pan Trail", - Path = "/Solar System/Planets/Saturn/Minor Moons/Shepherd Moons/Pan" + Path = "/Solar System/Planets/Saturn/Minor Moons/Shepherd Moons/Pan", + Focusable = false } } @@ -615,7 +628,8 @@ local PanLabel = { }, GUI = { Name = "Pan Label", - Path = "/Solar System/Planets/Saturn/Minor Moons/Shepherd Moons/Pan" + Path = "/Solar System/Planets/Saturn/Minor Moons/Shepherd Moons/Pan", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/saturn/rhea/layers/colorlayers/rhea_texture.asset b/data/assets/scene/solarsystem/planets/saturn/rhea/layers/colorlayers/rhea_texture.asset index a7e3702dfb..3261ef82a8 100644 --- a/data/assets/scene/solarsystem/planets/saturn/rhea/layers/colorlayers/rhea_texture.asset +++ b/data/assets/scene/solarsystem/planets/saturn/rhea/layers/colorlayers/rhea_texture.asset @@ -14,8 +14,7 @@ local Layer = { Identifier = "Texture", FilePath = texturesPath .. "rhea.jpg", Enabled = asset.enabled, - ZIndex = 5, - CacheSettings = { Enabled = false } + ZIndex = 5 } diff --git a/data/assets/scene/solarsystem/planets/saturn/rhea/rhea.asset b/data/assets/scene/solarsystem/planets/saturn/rhea/rhea.asset index 0c7e8d1b64..94d92d2a0c 100644 --- a/data/assets/scene/solarsystem/planets/saturn/rhea/rhea.asset +++ b/data/assets/scene/solarsystem/planets/saturn/rhea/rhea.asset @@ -72,7 +72,8 @@ local RheaLabel = { Tag = { "solarsystem_labels", "moon_labels", "major_moon_labels", "moon_major_saturn" }, GUI = { Name = "Rhea Label", - Path = "/Solar System/Planets/Saturn/Major Moons/Rhea" + Path = "/Solar System/Planets/Saturn/Major Moons/Rhea", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/saturn/rhea/trail.asset b/data/assets/scene/solarsystem/planets/saturn/rhea/trail.asset index f439933392..5185998463 100644 --- a/data/assets/scene/solarsystem/planets/saturn/rhea/trail.asset +++ b/data/assets/scene/solarsystem/planets/saturn/rhea/trail.asset @@ -27,6 +27,7 @@ local RheaTrail = { GUI = { Name = "Rhea Trail", Path = "/Solar System/Planets/Saturn/Major Moons/Rhea", + Focusable = false, Description = "Trail of Saturn's moon Rhea as observed by Saturn" } } diff --git a/data/assets/scene/solarsystem/planets/saturn/saturn.asset b/data/assets/scene/solarsystem/planets/saturn/saturn.asset index f85abdd7b8..7a7ee11ee4 100644 --- a/data/assets/scene/solarsystem/planets/saturn/saturn.asset +++ b/data/assets/scene/solarsystem/planets/saturn/saturn.asset @@ -41,7 +41,7 @@ local Saturn = { TextureUnlit = texturesPath .. "unlit_original_single.png", TextureColor = texturesPath .. "color_original_single.png", TextureTransparency = texturesPath .. "trans_original_single.png", - ColorFilter = 0.8, + ColorFilter = 0.9, NightFactor = 1.0, Size = 140445000, @@ -81,6 +81,7 @@ local SaturnLabel = { GUI = { Name = "Saturn Label", Path = "/Solar System/Planets/Saturn", + Focusable = false, Description = "Main planet label for Saturn" } } diff --git a/data/assets/scene/solarsystem/planets/saturn/tethys/layers/colorlayers/tethys_texture.asset b/data/assets/scene/solarsystem/planets/saturn/tethys/layers/colorlayers/tethys_texture.asset index 72b6215402..6dc5f6a1c8 100644 --- a/data/assets/scene/solarsystem/planets/saturn/tethys/layers/colorlayers/tethys_texture.asset +++ b/data/assets/scene/solarsystem/planets/saturn/tethys/layers/colorlayers/tethys_texture.asset @@ -14,8 +14,7 @@ local Layer = { Identifier = "Texture", FilePath = texturesPath .. "tethys.jpg", Enabled = asset.enabled, - ZIndex = 5, - CacheSettings = { Enabled = false } + ZIndex = 5 } diff --git a/data/assets/scene/solarsystem/planets/saturn/tethys/tethys.asset b/data/assets/scene/solarsystem/planets/saturn/tethys/tethys.asset index d895eb207a..2aa3ea72ab 100644 --- a/data/assets/scene/solarsystem/planets/saturn/tethys/tethys.asset +++ b/data/assets/scene/solarsystem/planets/saturn/tethys/tethys.asset @@ -70,7 +70,8 @@ local TethysLabel = { Tag = { "solarsystem_labels", "moon_labels", "major_moon_labels", "moon_major_saturn" }, GUI = { Name = "Tethys Label", - Path = "/Solar System/Planets/Saturn/Major Moons/Tethys" + Path = "/Solar System/Planets/Saturn/Major Moons/Tethys", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/saturn/tethys/trail.asset b/data/assets/scene/solarsystem/planets/saturn/tethys/trail.asset index 1a9539d8f6..1794256334 100644 --- a/data/assets/scene/solarsystem/planets/saturn/tethys/trail.asset +++ b/data/assets/scene/solarsystem/planets/saturn/tethys/trail.asset @@ -27,6 +27,7 @@ local TethysTrail = { GUI = { Name = "Tethys Trail", Path = "/Solar System/Planets/Saturn/Major Moons/Tethys", + Focusable = false, Description = "Trail of Saturn's moon Tethys as observed by Saturn" } } diff --git a/data/assets/scene/solarsystem/planets/saturn/titan/atmosphere.asset b/data/assets/scene/solarsystem/planets/saturn/titan/atmosphere.asset index ef2e18ab3f..957751e15e 100644 --- a/data/assets/scene/solarsystem/planets/saturn/titan/atmosphere.asset +++ b/data/assets/scene/solarsystem/planets/saturn/titan/atmosphere.asset @@ -43,7 +43,8 @@ local Atmosphere = { }, GUI = { Name = "Titan Atmosphere", - Path = "/Solar System/Planets/Saturn/Major Moons/Titan" + Path = "/Solar System/Planets/Saturn/Major Moons/Titan", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/saturn/titan/layers/colorlayers/cassini_sar_hisar_global_mosaic_351m_sweden.asset b/data/assets/scene/solarsystem/planets/saturn/titan/layers/colorlayers/cassini_sar_hisar_global_mosaic_351m_sweden.asset new file mode 100644 index 0000000000..84df419cd5 --- /dev/null +++ b/data/assets/scene/solarsystem/planets/saturn/titan/layers/colorlayers/cassini_sar_hisar_global_mosaic_351m_sweden.asset @@ -0,0 +1,36 @@ +local globe = asset.require("../../titan") + + + +local Layer = { + Identifier = "Cassini_SAR_HiSAR_Global_Mosaic_351m", + Name = "Cassini SAR - HiSAR Global Mosaic (351m)", + Enabled = asset.enabled, + ZIndex = 20, + FilePath = asset.resource("cassini_sar_hisar_global_mosaic_351m_sweden.wms"), + Description = [[This global map of Titan is a preliminary product showing coverage from + Synthetic Aperture Radar (SAR) and High Altitude Synthetic Aperture Radar (HiSAR) + images at a pixel resolution of 351 meters per pixel (m). This mosaic merges Cassini + swaths through flyby T104 into a single mosaic. (Description from URL)]] +} + + +asset.onInitialize(function() + openspace.globebrowsing.addLayer(globe.Titan.Identifier, "ColorLayers", Layer) +end) + +asset.onDeinitialize(function() + openspace.globebrowsing.deleteLayer(globe.Titan.Identifier, "ColorLayers", Layer) +end) + +asset.export("layer", Layer) + + + +asset.meta = { + Name = "Titan Cassini SAR - HiSAR Global Mosaic 351m", + Description = "Cassini global synthetic aperture radar image layer for Titan", + Author = "USGS", + URL = "https://astrogeology.usgs.gov/search/map/titan_cassini_sar_hisar_global_mosaic_351m", + License = "NASA/PDS" +} diff --git a/data/assets/scene/solarsystem/planets/saturn/titan/layers/colorlayers/cassini_sar_hisar_global_mosaic_351m_sweden.wms b/data/assets/scene/solarsystem/planets/saturn/titan/layers/colorlayers/cassini_sar_hisar_global_mosaic_351m_sweden.wms new file mode 100644 index 0000000000..2eddf8c8a3 --- /dev/null +++ b/data/assets/scene/solarsystem/planets/saturn/titan/layers/colorlayers/cassini_sar_hisar_global_mosaic_351m_sweden.wms @@ -0,0 +1,20 @@ + + + http://wms.itn.liu.se/Titan/HiSAR_Global_Mosaic_351m/tile/${z}/${y}/${x} + + + -180.0 + 90.0 + 180.0 + -90.0 + 46080 + 23040 + 7 + top + + EPSG:4326 + 512 + 512 + 1 + 10 + diff --git a/data/assets/scene/solarsystem/planets/saturn/titan/titan.asset b/data/assets/scene/solarsystem/planets/saturn/titan/titan.asset index cabd4f2813..6949745dc6 100644 --- a/data/assets/scene/solarsystem/planets/saturn/titan/titan.asset +++ b/data/assets/scene/solarsystem/planets/saturn/titan/titan.asset @@ -73,6 +73,7 @@ local TitanLabel = { GUI = { Name = "Titan Label", Path = "/Solar System/Planets/Saturn/Major Moons/Titan", + Focusable = false, Description = "Label for Saturn's moon Titan" } } diff --git a/data/assets/scene/solarsystem/planets/saturn/titan/trail.asset b/data/assets/scene/solarsystem/planets/saturn/titan/trail.asset index 942716d5f0..786f31cb84 100644 --- a/data/assets/scene/solarsystem/planets/saturn/titan/trail.asset +++ b/data/assets/scene/solarsystem/planets/saturn/titan/trail.asset @@ -27,6 +27,7 @@ local TitanTrail = { GUI = { Name = "Titan Trail", Path = "/Solar System/Planets/Saturn/Major Moons/Titan", + Focusable = false, Description = "Trail of Saturn's moon Titan as observed by Saturn" } } diff --git a/data/assets/scene/solarsystem/planets/saturn/trail.asset b/data/assets/scene/solarsystem/planets/saturn/trail.asset index 44617c9697..14cc40bc83 100644 --- a/data/assets/scene/solarsystem/planets/saturn/trail.asset +++ b/data/assets/scene/solarsystem/planets/saturn/trail.asset @@ -21,6 +21,7 @@ local SaturnTrail = { GUI = { Name = "Saturn Trail", Path = "/Solar System/Planets/Saturn", + Focusable = false, Description = "Trail of Saturn as observed by the Sun" } } diff --git a/data/assets/scene/solarsystem/planets/saturn/trail_barycenter.asset b/data/assets/scene/solarsystem/planets/saturn/trail_barycenter.asset index 383bb510bc..d90bafcea3 100644 --- a/data/assets/scene/solarsystem/planets/saturn/trail_barycenter.asset +++ b/data/assets/scene/solarsystem/planets/saturn/trail_barycenter.asset @@ -22,6 +22,7 @@ local SaturnBarycenterTrail = { GUI = { Name = "Saturn Barycenter Trail", Path = "/Solar System/Planets/Saturn", + Focusable = false, Description = "Trail of Saturn's Barycenter as observed by the Sun" } } diff --git a/data/assets/scene/solarsystem/planets/saturn/trail_earth.asset b/data/assets/scene/solarsystem/planets/saturn/trail_earth.asset index e35bd3acd5..73d1ee2959 100644 --- a/data/assets/scene/solarsystem/planets/saturn/trail_earth.asset +++ b/data/assets/scene/solarsystem/planets/saturn/trail_earth.asset @@ -22,6 +22,7 @@ local SaturnTrailEarth = { GUI = { Name = "Saturn trail from Earth", Path = "/Solar System/Planets/Saturn", + Focusable = false, Description = "Trail of Saturn as observed by the Earth" } } diff --git a/data/assets/scene/solarsystem/planets/saturn/transforms.asset b/data/assets/scene/solarsystem/planets/saturn/transforms.asset index 0d06778328..4045e93182 100644 --- a/data/assets/scene/solarsystem/planets/saturn/transforms.asset +++ b/data/assets/scene/solarsystem/planets/saturn/transforms.asset @@ -16,6 +16,7 @@ local SaturnBarycenter = { GUI = { Name = "Saturn Barycenter", Path = "/Solar System/Planets/Saturn", + Focusable = false, Hidden = true } } diff --git a/data/assets/scene/solarsystem/planets/uranus/inner_moons.asset b/data/assets/scene/solarsystem/planets/uranus/inner_moons.asset index eecd6fbe4b..50f42ba559 100644 --- a/data/assets/scene/solarsystem/planets/uranus/inner_moons.asset +++ b/data/assets/scene/solarsystem/planets/uranus/inner_moons.asset @@ -55,7 +55,8 @@ local CordeliaTrail = { }, GUI = { Name = "Cordelia Trail", - Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Cordelia" + Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Cordelia", + Focusable = false } } @@ -79,7 +80,8 @@ local CordeliaLabel = { Tag = { "solarsystem_labels", "moon_labels", "minor_moon_labels" }, GUI = { Name = "Cordelia Label", - Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Cordelia" + Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Cordelia", + Focusable = false } } @@ -134,7 +136,8 @@ local OpheliaTrail = { }, GUI = { Name = "Ophelia Trail", - Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Ophelia" + Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Ophelia", + Focusable = false } } @@ -158,7 +161,8 @@ local OpheliaLabel = { Tag = { "solarsystem_labels", "moon_labels", "minor_moon_labels" }, GUI = { Name = "Ophelia Label", - Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Ophelia" + Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Ophelia", + Focusable = false } } @@ -213,7 +217,8 @@ local BiancaTrail = { }, GUI = { Name = "Bianca Trail", - Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Bianca" + Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Bianca", + Focusable = false } } @@ -237,7 +242,8 @@ local BiancaLabel = { Tag = { "solarsystem_labels", "moon_labels", "minor_moon_labels" }, GUI = { Name = "Bianca Label", - Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Bianca" + Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Bianca", + Focusable = false } } @@ -292,7 +298,8 @@ local CressidaTrail = { }, GUI = { Name = "Cressida Trail", - Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Cressida" + Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Cressida", + Focusable = false } } @@ -316,7 +323,8 @@ local CressidaLabel = { Tag = { "solarsystem_labels", "moon_labels", "minor_moon_labels" }, GUI = { Name = "Cressida Label", - Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Cressida" + Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Cressida", + Focusable = false } } @@ -371,7 +379,8 @@ local DesdemonaTrail = { }, GUI = { Name = "Desdemona Trail", - Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Desdemona" + Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Desdemona", + Focusable = false } } @@ -395,7 +404,8 @@ local DesdemonaLabel = { Tag = { "solarsystem_labels", "moon_labels", "minor_moon_labels" }, GUI = { Name = "Desdemona Label", - Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Desdemona" + Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Desdemona", + Focusable = false } } @@ -450,7 +460,8 @@ local JulietTrail = { }, GUI = { Name = "Juliet Trail", - Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Juliet" + Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Juliet", + Focusable = false } } @@ -474,7 +485,8 @@ local JulietLabel = { Tag = { "solarsystem_labels", "moon_labels", "minor_moon_labels" }, GUI = { Name = "Juliet Label", - Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Juliet" + Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Juliet", + Focusable = false } } @@ -529,7 +541,8 @@ local PortiaTrail = { }, GUI = { Name = "Portia Trail", - Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Portia" + Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Portia", + Focusable = false } } @@ -553,7 +566,8 @@ local PortiaLabel = { Tag = { "solarsystem_labels", "moon_labels", "minor_moon_labels" }, GUI = { Name = "Portia Label", - Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Portia" + Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Portia", + Focusable = false } } @@ -608,7 +622,8 @@ local RosalindTrail = { }, GUI = { Name = "Rosalind Trail", - Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Rosalind" + Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Rosalind", + Focusable = false } } @@ -632,7 +647,8 @@ local RosalindLabel = { Tag = { "solarsystem_labels", "moon_labels", "minor_moon_labels" }, GUI = { Name = "Rosalind Label", - Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Rosalind" + Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Rosalind", + Focusable = false } } @@ -687,7 +703,8 @@ local CupidTrail = { }, GUI = { Name = "Cupid Trail", - Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Cupid" + Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Cupid", + Focusable = false } } @@ -711,7 +728,8 @@ local CupidLabel = { Tag = { "solarsystem_labels", "moon_labels", "minor_moon_labels" }, GUI = { Name = "Cupid Label", - Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Cupid" + Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Cupid", + Focusable = false } } @@ -766,7 +784,8 @@ local BelindaTrail = { }, GUI = { Name = "Belinda Trail", - Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Belinda" + Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Belinda", + Focusable = false } } @@ -790,7 +809,8 @@ local BelindaLabel = { Tag = { "solarsystem_labels", "moon_labels", "minor_moon_labels" }, GUI = { Name = "Belinda Label", - Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Belinda" + Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Belinda", + Focusable = false } } @@ -845,7 +865,8 @@ local PerditaTrail = { }, GUI = { Name = "Perdita Trail", - Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Perdita" + Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Perdita", + Focusable = false } } @@ -869,7 +890,8 @@ local PerditaLabel = { Tag = { "solarsystem_labels", "moon_labels", "minor_moon_labels" }, GUI = { Name = "Perdita Label", - Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Perdita" + Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Perdita", + Focusable = false } } @@ -924,7 +946,8 @@ local PuckTrail = { }, GUI = { Name = "Puck Trail", - Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Puck" + Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Puck", + Focusable = false } } @@ -948,7 +971,8 @@ local PuckLabel = { Tag = { "solarsystem_labels", "moon_labels", "minor_moon_labels" }, GUI = { Name = "Puck Label", - Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Puck" + Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Puck", + Focusable = false } } @@ -1003,7 +1027,8 @@ local MabTrail = { }, GUI = { Name = "Mab Trail", - Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Mab" + Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Mab", + Focusable = false } } @@ -1027,7 +1052,8 @@ local MabLabel = { Tag = { "solarsystem_labels", "moon_labels", "minor_moon_labels" }, GUI = { Name = "Mab Label", - Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Mab" + Path = "/Solar System/Planets/Uranus/Minor Moons/Inner Moons/Mab", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/uranus/irregular_prograde_moons.asset b/data/assets/scene/solarsystem/planets/uranus/irregular_prograde_moons.asset index 3502dfc264..7ff187da5a 100644 --- a/data/assets/scene/solarsystem/planets/uranus/irregular_prograde_moons.asset +++ b/data/assets/scene/solarsystem/planets/uranus/irregular_prograde_moons.asset @@ -55,7 +55,8 @@ local MargaretTrail = { }, GUI = { Name = "Margaret Trail", - Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Prograde Moons/Margaret" + Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Prograde Moons/Margaret", + Focusable = false } } @@ -79,7 +80,8 @@ local MargaretLabel = { Tag = { "solarsystem_labels", "moon_labels", "minor_moon_labels" }, GUI = { Name = "Margaret Label", - Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Prograde Moons/Margaret" + Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Prograde Moons/Margaret", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/uranus/irregular_retrograde_moons.asset b/data/assets/scene/solarsystem/planets/uranus/irregular_retrograde_moons.asset index 15fbab936d..0de2a028e1 100644 --- a/data/assets/scene/solarsystem/planets/uranus/irregular_retrograde_moons.asset +++ b/data/assets/scene/solarsystem/planets/uranus/irregular_retrograde_moons.asset @@ -55,7 +55,8 @@ local FranciscoTrail = { }, GUI = { Name = "Francisco Trail", - Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Francisco" + Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Francisco", + Focusable = false } } @@ -79,7 +80,8 @@ local FranciscoLabel = { Tag = { "solarsystem_labels", "moon_labels", "minor_moon_labels" }, GUI = { Name = "Francisco Label", - Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Francisco" + Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Francisco", + Focusable = false } } @@ -134,7 +136,8 @@ local CalibanTrail = { }, GUI = { Name = "Caliban Trail", - Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Caliban" + Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Caliban", + Focusable = false } } @@ -158,7 +161,8 @@ local CalibanLabel = { Tag = { "solarsystem_labels", "moon_labels", "minor_moon_labels" }, GUI = { Name = "Caliban Label", - Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Caliban" + Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Caliban", + Focusable = false } } @@ -213,7 +217,8 @@ local StephanoTrail = { }, GUI = { Name = "Stephano Trail", - Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Stephano" + Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Stephano", + Focusable = false } } @@ -237,7 +242,8 @@ local StephanoLabel = { Tag = { "solarsystem_labels", "moon_labels", "minor_moon_labels" }, GUI = { Name = "Stephano Label", - Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Stephano" + Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Stephano", + Focusable = false } } @@ -292,7 +298,8 @@ local TrinculoTrail = { }, GUI = { Name = "Trinculo Trail", - Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Trinculo" + Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Trinculo", + Focusable = false } } @@ -316,7 +323,8 @@ local TrinculoLabel = { Tag = { "solarsystem_labels", "moon_labels", "minor_moon_labels" }, GUI = { Name = "Trinculo Label", - Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Trinculo" + Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Trinculo", + Focusable = false } } @@ -371,7 +379,8 @@ local SycoraxTrail = { }, GUI = { Name = "Sycorax Trail", - Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Sycorax" + Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Sycorax", + Focusable = false } } @@ -395,7 +404,8 @@ local SycoraxLabel = { Tag = { "solarsystem_labels", "moon_labels", "minor_moon_labels" }, GUI = { Name = "Sycorax Label", - Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Sycorax" + Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Sycorax", + Focusable = false } } @@ -450,7 +460,8 @@ local ProsperoTrail = { }, GUI = { Name = "Prospero Trail", - Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Prospero" + Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Prospero", + Focusable = false } } @@ -474,7 +485,8 @@ local ProsperoLabel = { Tag = { "solarsystem_labels", "moon_labels", "minor_moon_labels" }, GUI = { Name = "Prospero Label", - Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Prospero" + Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Prospero", + Focusable = false } } @@ -529,7 +541,8 @@ local SetebosTrail = { }, GUI = { Name = "Setebos Trail", - Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Setebos" + Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Setebos", + Focusable = false } } @@ -553,7 +566,8 @@ local SetebosLabel = { Tag = { "solarsystem_labels", "moon_labels", "minor_moon_labels" }, GUI = { Name = "Setebos Label", - Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Setebos" + Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Setebos", + Focusable = false } } @@ -608,7 +622,8 @@ local FerdinandTrail = { }, GUI = { Name = "Ferdinand Trail", - Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Ferdinand" + Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Ferdinand", + Focusable = false } } @@ -632,7 +647,8 @@ local FerdinandLabel = { Tag = { "solarsystem_labels", "moon_labels", "minor_moon_labels" }, GUI = { Name = "Ferdinand Label", - Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Ferdinand" + Path = "/Solar System/Planets/Uranus/Minor Moons/Irregular Retrograde Moons/Ferdinand", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/uranus/layers/colorlayers/uranus_texture.asset b/data/assets/scene/solarsystem/planets/uranus/layers/colorlayers/uranus_texture.asset index ac086829a9..2e1fba51f6 100644 --- a/data/assets/scene/solarsystem/planets/uranus/layers/colorlayers/uranus_texture.asset +++ b/data/assets/scene/solarsystem/planets/uranus/layers/colorlayers/uranus_texture.asset @@ -14,8 +14,7 @@ local Layer = { Identifier = "Texture", FilePath = texturesPath .. "uranus.jpg", Enabled = asset.enabled, - ZIndex = 5, - CacheSettings = { Enabled = false } + ZIndex = 5 } diff --git a/data/assets/scene/solarsystem/planets/uranus/trail.asset b/data/assets/scene/solarsystem/planets/uranus/trail.asset index ef649343ca..75fa7afb5c 100644 --- a/data/assets/scene/solarsystem/planets/uranus/trail.asset +++ b/data/assets/scene/solarsystem/planets/uranus/trail.asset @@ -21,6 +21,7 @@ local UranusTrail = { GUI = { Name = "Uranus Trail", Path = "/Solar System/Planets/Uranus", + Focusable = false, Description = "Trail of Uranus as observed by the Sun" } } diff --git a/data/assets/scene/solarsystem/planets/uranus/trail_barycenter.asset b/data/assets/scene/solarsystem/planets/uranus/trail_barycenter.asset index cdd4fd6513..9c14f1ed97 100644 --- a/data/assets/scene/solarsystem/planets/uranus/trail_barycenter.asset +++ b/data/assets/scene/solarsystem/planets/uranus/trail_barycenter.asset @@ -22,6 +22,7 @@ local UranusBarycenterTrail = { GUI = { Name = "Uranus Barycenter Trail", Path = "/Solar System/Planets/Uranus", + Focusable = false, Description = "Trail of Uranus as observed by the Sun" } } diff --git a/data/assets/scene/solarsystem/planets/uranus/trail_earth.asset b/data/assets/scene/solarsystem/planets/uranus/trail_earth.asset index be915740bc..8cdcf86a55 100644 --- a/data/assets/scene/solarsystem/planets/uranus/trail_earth.asset +++ b/data/assets/scene/solarsystem/planets/uranus/trail_earth.asset @@ -22,6 +22,7 @@ local UranusTrailEarth = { GUI = { Name = "Uranus trail from Earth", Path = "/Solar System/Planets/Uranus", + Focusable = false, Description = "Trail of Uranus as observed by the Earth" } } diff --git a/data/assets/scene/solarsystem/planets/uranus/transforms.asset b/data/assets/scene/solarsystem/planets/uranus/transforms.asset index 6e05e5c0e7..168feca8f5 100644 --- a/data/assets/scene/solarsystem/planets/uranus/transforms.asset +++ b/data/assets/scene/solarsystem/planets/uranus/transforms.asset @@ -16,6 +16,7 @@ local UranusBarycenter = { GUI = { Name = "Uranus Barycenter", Path = "/Solar System/Planets/Uranus", + Focusable = false, Hidden = true } } diff --git a/data/assets/scene/solarsystem/planets/uranus/uranus.asset b/data/assets/scene/solarsystem/planets/uranus/uranus.asset index 5bda3b2e01..200e5b52ed 100644 --- a/data/assets/scene/solarsystem/planets/uranus/uranus.asset +++ b/data/assets/scene/solarsystem/planets/uranus/uranus.asset @@ -50,7 +50,8 @@ local UranusLabel = { Tag = { "solarsystem_labels" }, GUI = { Name = "Uranus Label", - Path = "/Solar System/Planets/Uranus" + Path = "/Solar System/Planets/Uranus", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/venus/atmosphere.asset b/data/assets/scene/solarsystem/planets/venus/atmosphere.asset index 66604edb9e..b6b4e95689 100644 --- a/data/assets/scene/solarsystem/planets/venus/atmosphere.asset +++ b/data/assets/scene/solarsystem/planets/venus/atmosphere.asset @@ -48,7 +48,8 @@ local Atmosphere = { GUI = { Name = "Venus Atmosphere", Path = "/Solar System/Planets/Venus", - Description = "Simulation of Venus' Atmosphere" + Description = "Simulation of Venus' Atmosphere", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/venus/layers/colorlayers/clouds_magellan_combo_newyork.asset b/data/assets/scene/solarsystem/planets/venus/layers/colorlayers/clouds_magellan_combo_newyork.asset index 09fee19707..ad3461137c 100644 --- a/data/assets/scene/solarsystem/planets/venus/layers/colorlayers/clouds_magellan_combo_newyork.asset +++ b/data/assets/scene/solarsystem/planets/venus/layers/colorlayers/clouds_magellan_combo_newyork.asset @@ -22,8 +22,7 @@ local Layer = { TileProvider = { Identifier = "Clouds", Name = "Clouds", - FilePath = texturesPath .. "venus_clouds.jpg", - CacheSettings = { Enabled = false } + FilePath = texturesPath .. "venus_clouds.jpg" } }, { diff --git a/data/assets/scene/solarsystem/planets/venus/layers/colorlayers/clouds_magellan_combo_utah.asset b/data/assets/scene/solarsystem/planets/venus/layers/colorlayers/clouds_magellan_combo_utah.asset index cf16f08f58..622db38ecb 100644 --- a/data/assets/scene/solarsystem/planets/venus/layers/colorlayers/clouds_magellan_combo_utah.asset +++ b/data/assets/scene/solarsystem/planets/venus/layers/colorlayers/clouds_magellan_combo_utah.asset @@ -22,8 +22,7 @@ local Layer = { TileProvider = { Identifier = "Clouds", Name = "Clouds", - FilePath = texturesPath .. "venus_clouds.jpg", - CacheSettings = { Enabled = false } + FilePath = texturesPath .. "venus_clouds.jpg" } }, { diff --git a/data/assets/scene/solarsystem/planets/venus/layers/colorlayers/venus_texture.asset b/data/assets/scene/solarsystem/planets/venus/layers/colorlayers/venus_texture.asset index e99aa4cad5..0fb8264797 100644 --- a/data/assets/scene/solarsystem/planets/venus/layers/colorlayers/venus_texture.asset +++ b/data/assets/scene/solarsystem/planets/venus/layers/colorlayers/venus_texture.asset @@ -14,8 +14,7 @@ local Clouds = { Identifier = "Clouds", FilePath = texturesPath .. "venus_clouds.jpg", Enabled = asset.enabled, - ZIndex = 20, - CacheSettings = { Enabled = false } + ZIndex = 20 } local Layer = { @@ -26,8 +25,7 @@ local Layer = { Settings = { Opacity = 0.48, Gamma = 0.48 - }, - CacheSettings = { Enabled = false } + } } diff --git a/data/assets/scene/solarsystem/planets/venus/trail.asset b/data/assets/scene/solarsystem/planets/venus/trail.asset index 5e8d0a37a9..aa91892736 100644 --- a/data/assets/scene/solarsystem/planets/venus/trail.asset +++ b/data/assets/scene/solarsystem/planets/venus/trail.asset @@ -20,7 +20,8 @@ local VenusTrail = { Tag = { "planetTrail_solarSystem", "planetTrail_terrestrial" }, GUI = { Name = "Venus Trail", - Path = "/Solar System/Planets/Venus" + Path = "/Solar System/Planets/Venus", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/venus/trail_barycenter.asset b/data/assets/scene/solarsystem/planets/venus/trail_barycenter.asset index ec46a030d9..68626464c7 100644 --- a/data/assets/scene/solarsystem/planets/venus/trail_barycenter.asset +++ b/data/assets/scene/solarsystem/planets/venus/trail_barycenter.asset @@ -21,7 +21,8 @@ local VenusBarycenterTrail = { Tag = { "planetTrail_solarSystem", "planetTrail_terrestrial" }, GUI = { Name = "Venus Barycenter Trail", - Path = "/Solar System/Planets/Venus" + Path = "/Solar System/Planets/Venus", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/planets/venus/trail_earth.asset b/data/assets/scene/solarsystem/planets/venus/trail_earth.asset index bbe796393e..50339342cb 100644 --- a/data/assets/scene/solarsystem/planets/venus/trail_earth.asset +++ b/data/assets/scene/solarsystem/planets/venus/trail_earth.asset @@ -23,6 +23,7 @@ local VenusTrailEarth = { GUI = { Name = "Venus trail from Earth", Path = "/Solar System/Planets/Venus", + Focusable = false, Description = "Alternate trail for Venus, showing Venus as observed from Earth" } } diff --git a/data/assets/scene/solarsystem/planets/venus/transforms.asset b/data/assets/scene/solarsystem/planets/venus/transforms.asset index bee0e82620..d110c95dfd 100644 --- a/data/assets/scene/solarsystem/planets/venus/transforms.asset +++ b/data/assets/scene/solarsystem/planets/venus/transforms.asset @@ -16,6 +16,7 @@ local VenusBarycenter = { GUI = { Name = "Venus Barycenter", Path = "/Solar System/Planets/Venus", + Focusable = false, Hidden = true } } diff --git a/data/assets/scene/solarsystem/planets/venus/venus.asset b/data/assets/scene/solarsystem/planets/venus/venus.asset index 8d536081c5..036ccd155f 100644 --- a/data/assets/scene/solarsystem/planets/venus/venus.asset +++ b/data/assets/scene/solarsystem/planets/venus/venus.asset @@ -65,13 +65,14 @@ local VenusLabel = { BlendMode = "Additive", EnableFading = true, FadeUnit = "au", - FadeDistances = { 1.5, 25.0 }, + FadeDistances = { 0.75, 25.0 }, FadeWidths = { 1.0, 35.0 } }, Tag = { "solarsystem_labels" }, GUI = { - Name = "Venus Label", - Path = "/Solar System/Planets/Venus" + Name = "Venus Label", + Path = "/Solar System/Planets/Venus", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/sssb/amor_asteroid.asset b/data/assets/scene/solarsystem/sssb/amor_asteroid.asset index b89b521494..5ab657307f 100644 --- a/data/assets/scene/solarsystem/sssb/amor_asteroid.asset +++ b/data/assets/scene/solarsystem/sssb/amor_asteroid.asset @@ -26,6 +26,7 @@ local Object = { GUI = { Name = "Amor Asteroids", Path = "/Solar System/Small Bodies", + Focusable = false, Description = [[Earth-approaching Near-Earth-Asteroids with orbits exterior to Earth's but interior to Mars'.]] } diff --git a/data/assets/scene/solarsystem/sssb/apollo_asteroid.asset b/data/assets/scene/solarsystem/sssb/apollo_asteroid.asset index 8f2b1ea3d1..22624d2e33 100644 --- a/data/assets/scene/solarsystem/sssb/apollo_asteroid.asset +++ b/data/assets/scene/solarsystem/sssb/apollo_asteroid.asset @@ -26,6 +26,7 @@ local Object = { GUI = { Name = "Apollo Asteroids", Path = "/Solar System/Small Bodies", + Focusable = false, Description = [[Earth-crossing Near-Earth-Asteroids with semi-major axes larger than Earth's.]] } diff --git a/data/assets/scene/solarsystem/sssb/astraea.asset b/data/assets/scene/solarsystem/sssb/astraea.asset index 8679e1ec84..891a2e9737 100644 --- a/data/assets/scene/solarsystem/sssb/astraea.asset +++ b/data/assets/scene/solarsystem/sssb/astraea.asset @@ -30,7 +30,8 @@ local AstraeaTrail = { }, GUI = { Name = "5 Astraea Trail", - Path = "/Solar System/Interstellar" + Path = "/Solar System/Interstellar", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/sssb/aten_asteroid.asset b/data/assets/scene/solarsystem/sssb/aten_asteroid.asset index 1c7c7b97ae..0e22950cd7 100644 --- a/data/assets/scene/solarsystem/sssb/aten_asteroid.asset +++ b/data/assets/scene/solarsystem/sssb/aten_asteroid.asset @@ -26,6 +26,7 @@ local Object = { GUI = { Name = "Aten Asteroids", Path = "/Solar System/Small Bodies", + Focusable = false, Description = [[Earth-crossing Near-Earth-Asteroids with semi-major axes smaller than Earth's.]] } diff --git a/data/assets/scene/solarsystem/sssb/atira_asteroid.asset b/data/assets/scene/solarsystem/sssb/atira_asteroid.asset index 000904556b..4c681e9100 100644 --- a/data/assets/scene/solarsystem/sssb/atira_asteroid.asset +++ b/data/assets/scene/solarsystem/sssb/atira_asteroid.asset @@ -26,6 +26,7 @@ local Object = { GUI = { Name = "Atira Asteroids", Path = "/Solar System/Small Bodies", + Focusable = false, Description = [[Near-Earth-Asteroids whose orbits are contained entirely within the orbit of the Earth.]] } diff --git a/data/assets/scene/solarsystem/sssb/c2019y4atlas.asset b/data/assets/scene/solarsystem/sssb/c2019y4atlas.asset index 3dafeab613..c3f8bd2fe2 100644 --- a/data/assets/scene/solarsystem/sssb/c2019y4atlas.asset +++ b/data/assets/scene/solarsystem/sssb/c2019y4atlas.asset @@ -35,7 +35,8 @@ local C2019Y4AtlasTrail = { }, GUI = { Name = "C2019 Y4 Atlas Trail", - Path = "/Solar System/Small Bodies" + Path = "/Solar System/Small Bodies", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/sssb/centaur_asteroid.asset b/data/assets/scene/solarsystem/sssb/centaur_asteroid.asset index 688e139197..1f5a7a8e8f 100644 --- a/data/assets/scene/solarsystem/sssb/centaur_asteroid.asset +++ b/data/assets/scene/solarsystem/sssb/centaur_asteroid.asset @@ -26,6 +26,7 @@ local Object = { GUI = { Name = "Centaur Asteroids", Path = "/Solar System/Small Bodies", + Focusable = false, Description = [[Asteroids with either a perihelion or a semi-major axis between those of the four outer planets.]] } diff --git a/data/assets/scene/solarsystem/sssb/chiron-type_comet.asset b/data/assets/scene/solarsystem/sssb/chiron-type_comet.asset index 13ac881cd8..b16a2eaa08 100644 --- a/data/assets/scene/solarsystem/sssb/chiron-type_comet.asset +++ b/data/assets/scene/solarsystem/sssb/chiron-type_comet.asset @@ -26,6 +26,7 @@ local Object = { GUI = { Name = "Chiron-type Comets", Path = "/Solar System/Small Bodies", + Focusable = false, Description = [[Comets with a Tisserand's parameter with respect to Jupiter of greater than 3 and a semi-major axis greater than that of Jupiter.]] } diff --git a/data/assets/scene/solarsystem/sssb/encke-type_comet.asset b/data/assets/scene/solarsystem/sssb/encke-type_comet.asset index 3ce380a567..584e4389d2 100644 --- a/data/assets/scene/solarsystem/sssb/encke-type_comet.asset +++ b/data/assets/scene/solarsystem/sssb/encke-type_comet.asset @@ -26,6 +26,7 @@ local Object = { GUI = { Name = "Encke-type Comets", Path = "/Solar System/Small Bodies", + Focusable = false, Description = [[Comets with a Tisserand's parameter with respect to Jupiter of greater than 3 and a semi-major axis less than that of Jupiter.]] } diff --git a/data/assets/scene/solarsystem/sssb/halley-type_comet.asset b/data/assets/scene/solarsystem/sssb/halley-type_comet.asset index d135cfbbba..d32fdb162b 100644 --- a/data/assets/scene/solarsystem/sssb/halley-type_comet.asset +++ b/data/assets/scene/solarsystem/sssb/halley-type_comet.asset @@ -26,6 +26,7 @@ local Object = { GUI = { Name = "Halley-type Comets", Path = "/Solar System/Small Bodies", + Focusable = false, Description = "Periodic comets with an orbital period between 20 and 200 years." } } diff --git a/data/assets/scene/solarsystem/sssb/inner_main_belt_asteroid.asset b/data/assets/scene/solarsystem/sssb/inner_main_belt_asteroid.asset index 2b843dd9b3..939251108a 100644 --- a/data/assets/scene/solarsystem/sssb/inner_main_belt_asteroid.asset +++ b/data/assets/scene/solarsystem/sssb/inner_main_belt_asteroid.asset @@ -26,6 +26,7 @@ local Object = { GUI = { Name = "Inner Main Asteroid Belt", Path = "/Solar System/Small Bodies", + Focusable = false, Description = [[Asteroids with a semi-major axis less than 2.0 AU and a perihelion distance greater than 1.666 AU.]] } diff --git a/data/assets/scene/solarsystem/sssb/itokawa.asset b/data/assets/scene/solarsystem/sssb/itokawa.asset index a7de3618cf..42ea794cd2 100644 --- a/data/assets/scene/solarsystem/sssb/itokawa.asset +++ b/data/assets/scene/solarsystem/sssb/itokawa.asset @@ -38,6 +38,7 @@ local ItokawaTrail = { GUI = { Name = "Itokawa Trail", Path = "/Solar System/Small Bodies/Itokawa", + Focusable = false, Description = [[Trail of asteroid 25143 Itokawa from 1950 JAN 1 00:00:00 to 2050 JAN 1 00:00:00. Data from JPL Horizons]] } diff --git a/data/assets/scene/solarsystem/sssb/jupiter-family_comet.asset b/data/assets/scene/solarsystem/sssb/jupiter-family_comet.asset index d38b10968c..d41134268a 100644 --- a/data/assets/scene/solarsystem/sssb/jupiter-family_comet.asset +++ b/data/assets/scene/solarsystem/sssb/jupiter-family_comet.asset @@ -26,6 +26,7 @@ local Object = { GUI = { Name = "Jupiter-family Comets", Path = "/Solar System/Small Bodies", + Focusable = false, Description = [[Comets with a Tisserand's parameter with respect to Jupiter of between 2 and 3.]] } diff --git a/data/assets/scene/solarsystem/sssb/jupiter_trojan_asteroid.asset b/data/assets/scene/solarsystem/sssb/jupiter_trojan_asteroid.asset index ea06683651..56697005a4 100644 --- a/data/assets/scene/solarsystem/sssb/jupiter_trojan_asteroid.asset +++ b/data/assets/scene/solarsystem/sssb/jupiter_trojan_asteroid.asset @@ -26,6 +26,7 @@ local Object = { GUI = { Name = "Jupiter Trojan Asteroids", Path = "/Solar System/Small Bodies", + Focusable = false, Description = [[Asteroids trapped in Jupiter's L4/L5 Lagrange points (semimajor axis of between 4.6 and 5.5 AU), with an eccentricity of less than 0.3.]] } diff --git a/data/assets/scene/solarsystem/sssb/main_belt_asteroid.asset b/data/assets/scene/solarsystem/sssb/main_belt_asteroid.asset index 76978d5826..48876f918b 100644 --- a/data/assets/scene/solarsystem/sssb/main_belt_asteroid.asset +++ b/data/assets/scene/solarsystem/sssb/main_belt_asteroid.asset @@ -27,6 +27,7 @@ local Object = { GUI = { Name = "Main Asteroid Belt", Path = "/Solar System/Small Bodies", + Focusable = false, Description = [[Asteroids with a semi-major axis of between 2.0 and 3.2 AU, and a perihelion distance greater than 1.666 AU.]] } diff --git a/data/assets/scene/solarsystem/sssb/mars-crossing_asteroid.asset b/data/assets/scene/solarsystem/sssb/mars-crossing_asteroid.asset index 2e173fa8cb..6e60ac5f21 100644 --- a/data/assets/scene/solarsystem/sssb/mars-crossing_asteroid.asset +++ b/data/assets/scene/solarsystem/sssb/mars-crossing_asteroid.asset @@ -26,6 +26,7 @@ local Object = { GUI = { Name = "Mars-crossing Asteroids", Path = "/Solar System/Small Bodies", + Focusable = false, Description = [[Asteroids that cross the orbit of Mars, with a semi-major axis of less than 3.2 AU, and a perihelion distance of between 1.3 and 1.666 AU.]] } diff --git a/data/assets/scene/solarsystem/sssb/mpc.asset b/data/assets/scene/solarsystem/sssb/mpc.asset new file mode 100644 index 0000000000..1c20a51f00 --- /dev/null +++ b/data/assets/scene/solarsystem/sssb/mpc.asset @@ -0,0 +1,59 @@ +local transforms = asset.require("scene/solarsystem/sun/transforms") + + + +local mpcorb = asset.resource({ + Type = "UrlSynchronization", + Name = "Minor Planet Center Orbital File", + Identifier = "mpc_orb", + Url = "https://minorplanetcenter.net/iau/MPCORB/MPCORB.DAT" +}) + + +local Object = { + Identifier = "MinorPlanetCenterObjects", + Parent = transforms.SunEclipJ2000.Identifier, + Renderable = { + Type = "RenderableOrbitalKepler", + Path = mpcorb, + Format = "MPC", + Segments = 200, + SegmentQuality = 4, + Color = { 0.8, 0.15, 0.2 }, + TrailFade = 11, + PointSizeExponent = 9.2 + }, + GUI = { + Name = "Minor Planet Center Bodies", + Path = "/Solar System/Small Bodies", + Focusable = false, + Description = [[The full catalog of objects from the IAU's Minor Planets Center. + Specifically from the publications of the Minor Planets Circulars, the Minor Planets + Orbit Supplement, and the Minor Planet Electronic Circulars. For more information + visit https://minorplanetcenter.net/iau/MPCORB.html.]] + } +} + + +asset.onInitialize(function() + openspace.addSceneGraphNode(Object) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(Object) +end) + +asset.export(Object) + + + +asset.meta = { + Name = "Minor Planets Center Database", + Description = [[The full catalog of objects from the IAU's Minor Planets Center. + Specifically from the publications of the Minor Planets Circulars, the Minor Planets + Orbit Supplement, and the Minor Planet Electronic Circulars. For more information + visit https://minorplanetcenter.net/iau/MPCORB.html.]], + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/scene/solarsystem/sssb/outer_main_belt_asteroid.asset b/data/assets/scene/solarsystem/sssb/outer_main_belt_asteroid.asset index be738fa2a0..cc082e8074 100644 --- a/data/assets/scene/solarsystem/sssb/outer_main_belt_asteroid.asset +++ b/data/assets/scene/solarsystem/sssb/outer_main_belt_asteroid.asset @@ -26,6 +26,7 @@ local Object = { GUI = { Name = "Outer Main Asteroid Belt", Path = "/Solar System/Small Bodies", + Focusable = false, Description = [[Asteroids with a semi-major axis of between 3.2 and 4.6 AU.]] } } diff --git a/data/assets/scene/solarsystem/sssb/pha.asset b/data/assets/scene/solarsystem/sssb/pha.asset index 35465484a8..60b3505f49 100644 --- a/data/assets/scene/solarsystem/sssb/pha.asset +++ b/data/assets/scene/solarsystem/sssb/pha.asset @@ -26,6 +26,7 @@ local Object = { GUI = { Name = "Potentially Hazardous Asteroids", Path = "/Solar System/Small Bodies", + Focusable = false, Description = [[Asteroids that are deemed potentially hazardous to Earth based on their close approaches. All asteroids with an Earth Minimum Orbit Intersection Distance (MOID) of 0.05 AU or less, and with an absolute magnitude (H) of 22.0 or diff --git a/data/assets/scene/solarsystem/sssb/swifttuttle.asset b/data/assets/scene/solarsystem/sssb/swifttuttle.asset index f4d5c82348..3a3bfc02f3 100644 --- a/data/assets/scene/solarsystem/sssb/swifttuttle.asset +++ b/data/assets/scene/solarsystem/sssb/swifttuttle.asset @@ -30,7 +30,8 @@ local SwiftTuttleTrail = { }, GUI = { Name = "Swift Tuttle Trail", - Path = "/Solar System/Small Bodies" + Path = "/Solar System/Small Bodies", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/sssb/tesla_roadster.asset b/data/assets/scene/solarsystem/sssb/tesla_roadster.asset index d17437a097..a62fd5cf10 100644 --- a/data/assets/scene/solarsystem/sssb/tesla_roadster.asset +++ b/data/assets/scene/solarsystem/sssb/tesla_roadster.asset @@ -30,7 +30,8 @@ local TeslaRoadsterTrail = { }, GUI = { Name = "Tesla Roadster Trail", - Path = "/Solar System/Small Bodies" + Path = "/Solar System/Small Bodies", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/sssb/transneptunian_object_asteroid.asset b/data/assets/scene/solarsystem/sssb/transneptunian_object_asteroid.asset index fab0c4d349..3c39ebbd1c 100644 --- a/data/assets/scene/solarsystem/sssb/transneptunian_object_asteroid.asset +++ b/data/assets/scene/solarsystem/sssb/transneptunian_object_asteroid.asset @@ -26,6 +26,7 @@ local Object = { GUI = { Name = "Transneptunian Object Asteroids", Path = "/Solar System/Small Bodies", + Focusable = false, Description = [[Any minor or dwarf planets in the solar system that orbit the Sun at a greater average distance than Neptune (semi-major axis of 30.1 AU).]] } diff --git a/data/assets/scene/solarsystem/sun/EUV_layer.asset b/data/assets/scene/solarsystem/sun/euv_layer.asset similarity index 68% rename from data/assets/scene/solarsystem/sun/EUV_layer.asset rename to data/assets/scene/solarsystem/sun/euv_layer.asset index 6fd0757944..a5a955740b 100644 --- a/data/assets/scene/solarsystem/sun/EUV_layer.asset +++ b/data/assets/scene/solarsystem/sun/euv_layer.asset @@ -1,4 +1,3 @@ -local propertyHelper = asset.require("util/property_helper") local transforms = asset.require("./transforms") @@ -34,26 +33,10 @@ local EUVLayer = { } local ToggleEuv = { - Identifier = "os.solarsystem.ToggleEuv", + Identifier = "os.solarsystem.sun.ToggleEuv", Name = "Toggle EUV layer", Command = [[ - if openspace.propertyValue("Scene.EUV-Layer-bastille-day-2000.Renderable.Enabled") then - openspace.setPropertyValueSingle( - "Scene.EUV-Layer-bastille-day-2000.Renderable.Fade", - 0.0, - openspace.propertyValue("OpenSpaceEngine.FadeDuration"), - "Linear", - 'openspace.setPropertyValueSingle("Scene.EUV-Layer-bastille-day-2000.Renderable.Enabled", false)' - ) - else - openspace.setPropertyValueSingle("Scene.EUV-Layer-bastille-day-2000.Renderable.Enabled", true) - openspace.setPropertyValueSingle( - "Scene.EUV-Layer-bastille-day-2000.Renderable.Fade", - 1.0, - openspace.propertyValue("OpenSpaceEngine.FadeDuration"), - "Linear" - ) - end + openspace.toggleFade("Scene.EUV-Layer-bastille-day-2000.Renderable") ]], Documentation = "Toggle EUV layer of sun", GuiPath = "/Bastille-Day 2000", diff --git a/data/assets/scene/solarsystem/sun/glare.asset b/data/assets/scene/solarsystem/sun/glare.asset index 14223d174e..0f6d61997a 100644 --- a/data/assets/scene/solarsystem/sun/glare.asset +++ b/data/assets/scene/solarsystem/sun/glare.asset @@ -17,7 +17,7 @@ local SunGlare = { Type = "RenderablePlaneImageLocal", Size = 41109609582.189, Origin = "Center", - Billboard = true, + Billboard = "Camera Position Normal", Texture = textures .. "halo.png", BlendMode = "Additive", Opacity = 0.65, @@ -26,6 +26,7 @@ local SunGlare = { GUI = { Name = "Sun Glare", Path = "/Solar System/Sun", + Focusable = false, Description = "Sun glare effect. Enabled by default instead of sun globe" } } diff --git a/data/assets/scene/solarsystem/sun/habitablezone.asset b/data/assets/scene/solarsystem/sun/habitablezone.asset index 4a86d2fcd5..4b7f167aa5 100644 --- a/data/assets/scene/solarsystem/sun/habitablezone.asset +++ b/data/assets/scene/solarsystem/sun/habitablezone.asset @@ -16,8 +16,9 @@ local HabitableZone = { Optimistic = true }, GUI = { - Name = "Sun Habitable Zone", + Name = "Sun's Habitable Zone", Path = "/Solar System/Sun", + Focusable = false, Description = "Habitable zone for the sun in our solar system" } } diff --git a/data/assets/scene/solarsystem/sun/layers/colorlayers/sun_texture.asset b/data/assets/scene/solarsystem/sun/layers/colorlayers/sun_texture.asset index bb0793ad1f..608c538518 100644 --- a/data/assets/scene/solarsystem/sun/layers/colorlayers/sun_texture.asset +++ b/data/assets/scene/solarsystem/sun/layers/colorlayers/sun_texture.asset @@ -14,8 +14,7 @@ local Layer = { Identifier = "Texture", FilePath = texturesPath .. "sun.jpg", Enabled = asset.enabled, - ZIndex = 5, - CacheSettings = { Enabled = false } + ZIndex = 5 } diff --git a/data/assets/scene/solarsystem/sun/sun.asset b/data/assets/scene/solarsystem/sun/sun.asset index 1d09d395e3..773b9b74ed 100644 --- a/data/assets/scene/solarsystem/sun/sun.asset +++ b/data/assets/scene/solarsystem/sun/sun.asset @@ -18,7 +18,7 @@ local Sun = { }, ApproachFactor = 15.0, GUI = { - Name = "Sun", + Name = "Sun Surface", Path = "/Solar System/Sun", Description = "Globe for the sun in our solar system" } @@ -45,6 +45,7 @@ local SunLabel = { GUI = { Name = "Sun Label", Path = "/Solar System/Sun", + Focusable = false, Description = "Label for the sun in our solar system" } } diff --git a/data/assets/scene/solarsystem/sun/transforms.asset b/data/assets/scene/solarsystem/sun/transforms.asset index 4cd42b86e9..1f44ee8004 100644 --- a/data/assets/scene/solarsystem/sun/transforms.asset +++ b/data/assets/scene/solarsystem/sun/transforms.asset @@ -14,6 +14,7 @@ local SolarSystemBarycenter = { GUI = { Name = "Solar System Barycenter", Path = "/Solar System", + Focusable = false, Hidden = true } } @@ -32,6 +33,7 @@ local SunCenter = { Name = "Sun Center", Path = "/Solar System/Sun", Description = "Spice frame for the Sun", + Focusable = false, Hidden = true } } @@ -55,6 +57,7 @@ local SunIAU = { GUI = { Name = "Sun IAU", Path = "/Solar System/Sun", + Focusable = false, Hidden = true } } @@ -77,6 +80,7 @@ local SunEclipJ2000 = { GUI = { Name = "Sun J2000", Path = "/Solar System/Sun", + Focusable = false, Hidden = true } } diff --git a/data/assets/scene/solarsystem/telescopes/euclid/mission.asset b/data/assets/scene/solarsystem/telescopes/euclid/mission.asset index a5379df34a..3509208015 100644 --- a/data/assets/scene/solarsystem/telescopes/euclid/mission.asset +++ b/data/assets/scene/solarsystem/telescopes/euclid/mission.asset @@ -1,7 +1,7 @@ local Mission = { Identifier = "Euclid", Name = "Euclid", - Image = "https://www.esa.int/var/esa/storage/images/esa_multimedia/images/2013/01/euclid_logo/12493233-3-eng-GB/Euclid_logo_pillars.png", + Image = "https://data.openspaceproject.com/missions/euclid/Euclid_logo_pillars.png", Description = [[Euclid is designed to explore the evolution of the dark universe. It will make a 3D-map of the universe (with time as the third dimension) by observing billions of galaxies out to 10 billion light-years, across more than a third of the sky. While dark energy accelerates the expansion of the universe and dark matter governs the growth of cosmic structures, scientists remain unsure about what dark energy and dark matter actually are. diff --git a/data/assets/scene/solarsystem/telescopes/euclid/trails.asset b/data/assets/scene/solarsystem/telescopes/euclid/trails.asset index b91f91ad34..dbd2540a1c 100644 --- a/data/assets/scene/solarsystem/telescopes/euclid/trails.asset +++ b/data/assets/scene/solarsystem/telescopes/euclid/trails.asset @@ -2,6 +2,7 @@ local kernels = asset.require("./kernels") local earth = asset.require("scene/solarsystem/planets/earth/transforms") local solarsystem = asset.require("scene/solarsystem/sun/transforms") local transforms = asset.require("scene/solarsystem/planets/earth/lagrange_points/l2/transforms") +local l2kernels = asset.require("scene/solarsystem/planets/earth/lagrange_points/l2/kernels") local coreKernels = asset.require("spice/core") @@ -25,7 +26,8 @@ local EuclidTrailSun = { }, GUI = { Name = "Euclid Trail (Sun)", - Path = "/Solar System/Telescopes/Euclid" + Path = "/Solar System/Telescopes/Euclid", + Focusable = false } } @@ -46,7 +48,8 @@ local EuclidTrailEarth = { }, GUI = { Name = "Euclid Trail (Earth)", - Path = "/Solar System/Telescopes/Euclid" + Path = "/Solar System/Telescopes/Euclid", + Focusable = false } } @@ -63,7 +66,7 @@ local EuclidTrailOrbit = { Translation = { Type = "SpiceTranslation", Target = kernels.ID.Euclid, - Observer = transforms.ID.L2, + Observer = l2kernels.ID.L2, Frame = coreKernels.Frame.Galactic }, Color = { 0.863, 0.0, 0.902 }, @@ -73,6 +76,7 @@ local EuclidTrailOrbit = { GUI = { Name = "Euclid Orbit Trail", Path = "/Solar System/Telescopes/Euclid", + Focusable = false, Description = "Euclid Orbit Trail relative to L2" } } @@ -90,8 +94,8 @@ local EuclidTrailCoRevOrbit = { Translation = { Type = "SpiceTranslation", Target = kernels.ID.Euclid, - Observer = transforms.ID.L2, - Frame = transforms.Frame.L2Corevolving + Observer = l2kernels.ID.L2, + Frame = l2kernels.Frame.L2Corevolving }, Color = { 0.863, 0.0, 0.902 }, Period = 182.621099, -- About 6 months @@ -100,6 +104,7 @@ local EuclidTrailCoRevOrbit = { GUI = { Name = "Euclid L2 Co-Revolving Orbit Trail", Path = "/Solar System/Telescopes/Euclid", + Focusable = false, Description = "Euclid Orbit Trail relative to L2" } } diff --git a/data/assets/scene/solarsystem/telescopes/gaia/dashboard.asset b/data/assets/scene/solarsystem/telescopes/gaia/dashboard.asset index 1c5bc07537..bc7598dc81 100644 --- a/data/assets/scene/solarsystem/telescopes/gaia/dashboard.asset +++ b/data/assets/scene/solarsystem/telescopes/gaia/dashboard.asset @@ -8,9 +8,9 @@ local distance = { Identifier = "GaiaEarthDistance", GuiName = "Gaia Earth Distance", SourceType = "Node", - SourceNodeName = gaia.Gaia.Identifier, + SourceNodeIdentifier = gaia.Gaia.Identifier, DestinationType = "Node Surface", - DestinationNodeName = earth.Earth.Identifier + DestinationNodeIdentifier = earth.Earth.Identifier } diff --git a/data/assets/scene/solarsystem/telescopes/gaia/trail.asset b/data/assets/scene/solarsystem/telescopes/gaia/trail.asset index cc159ca913..a28902e69d 100644 --- a/data/assets/scene/solarsystem/telescopes/gaia/trail.asset +++ b/data/assets/scene/solarsystem/telescopes/gaia/trail.asset @@ -35,7 +35,8 @@ local GaiaTrail = { }, GUI = { Name = "Gaia Trail", - Path = "/Solar System/Telescopes/Gaia" + Path = "/Solar System/Telescopes/Gaia", + Focusable = false } } @@ -61,7 +62,8 @@ local GaiaTrailEclip = { }, GUI = { Name = "Gaia Ecliptic Trail", - Path = "/Solar System/Telescopes/Gaia" + Path = "/Solar System/Telescopes/Gaia", + Focusable = false } } diff --git a/data/assets/scene/solarsystem/telescopes/jwst/actions.asset b/data/assets/scene/solarsystem/telescopes/jwst/actions.asset index ed9854d6f8..6b2402fe83 100644 --- a/data/assets/scene/solarsystem/telescopes/jwst/actions.asset +++ b/data/assets/scene/solarsystem/telescopes/jwst/actions.asset @@ -1,12 +1,7 @@ local ToggleLagrangianPoints = { Identifier = "os.jwst.ToggleLagrangianPoints", Name = "Toggle Lagrangian points", - Command = [[ - local list = openspace.property("{lagrange_points_earth}.Renderable.Enabled") - for _,v in pairs(list) do - openspace.setPropertyValueSingle(v, not openspace.propertyValue(v)) - end - ]], + Command = [[openspace.toggleFade("{lagrange_points_earth}.Renderable")]], Documentation = "Toggle points and labels for the Lagrangian points for Earth Sun system", GuiPath = "/JWST", IsLocal = false @@ -15,11 +10,11 @@ local ToggleLagrangianPoints = { local ToggleHudf = { Identifier = "os.jwst.ToggleHudf", Name = "Toggle Hubble Ultra Deep Field", + -- The tag used here matches both a screenspace renderable and a scene graph node, + -- hence the need for the double toggleFade Command = [[ - local list = openspace.property("{mission_jwst_hudf}.*.Enabled") - for _,v in pairs(list) do - openspace.setPropertyValueSingle(v, not openspace.propertyValue(v)) - end + openspace.toggleFade("{mission_jwst_hudf}") + openspace.toggleFade("{mission_jwst_hudf}.Renderable") ]], Documentation = "Toggle Hubble Ultra Deep Field image and line towards its coordinate", GuiPath = "/JWST", @@ -29,12 +24,7 @@ local ToggleHudf = { local ToggleL2 = { Identifier = "os.jwst.ToggleL2", Name = "Toggle L2 line and small L2 label", - Command = [[ - local list = openspace.property("{lagrange_points_earth_l2_small}.*.Enabled") - for _,v in pairs(list) do - openspace.setPropertyValueSingle(v, not openspace.propertyValue(v)) - end - ]], + Command = [[openspace.toggleFade("{lagrange_points_earth_l2_small}.Renderable")]], Documentation = "Toggle L2 label, point and line", GuiPath = "/JWST", IsLocal = false @@ -43,12 +33,7 @@ local ToggleL2 = { local ToggleFov = { Identifier = "os.jwst.ToggleFov", Name = "Toggle JWST field of view and view band", - Command = [[ - local list = openspace.property("{mission_jwst_fov}.*.Enabled") - for _,v in pairs(list) do - openspace.setPropertyValueSingle(v, not openspace.propertyValue(v)) - end - ]], + Command = [[openspace.toggleFade("{mission_jwst_fov}.Renderable")]], Documentation = "Toggle James Webb Space Telecope field of view and view band", GuiPath = "/JWST", IsLocal = false @@ -82,8 +67,7 @@ local ToggleSunTrail = { Identifier = "os.jwst.ToggleSunTrail", Name = "Toggle JWST Sun trail", Command = [[ - local value = openspace.propertyValue("Scene.JWSTSunTrail.Renderable.Enabled") - openspace.setPropertyValueSingle("Scene.JWSTSunTrail.Renderable.Enabled", not value) + openspace.toggleFade("Scene.JWSTSunTrail.Renderable") ]], Documentation = "Toggle JWST trail relative to the Sun", GuiPath = "/JWST", @@ -94,15 +78,8 @@ local ToggleTrailsExceptMoon = { Identifier = "os.jwst.ToggleTrailsExceptMoon", Name = "Toggle trails (except Moon)", Command = [[ - local list = openspace.property("{planetTrail_solarSystem}.Renderable.Enabled") - for _,v in pairs(list) do - openspace.setPropertyValueSingle(v, not openspace.propertyValue(v)) - end - local moonlist = openspace.property("{moonTrail_solarSystem}.Renderable.Enabled") - for _,v in pairs(moonlist) do - openspace.setPropertyValueSingle(v, not openspace.propertyValue(v)) - end - openspace.setPropertyValueSingle("Scene.MoonTrail.Renderable.Enabled", true) + openspace.toggleFade("{planetTrail_solarSystem}.Renderable") + openspace.toggleFade("{moonTrail_solarSystem~moon_earth}.Renderable") ]], Documentation = "Toggle all planet and moon trails, except the Moon", GuiPath = "/JWST", @@ -113,14 +90,9 @@ local ToggleJwstTrails = { Identifier = "os.jwst.ToggleJwstTrails", Name = "Toggle JWST trail", Command = [[ - local list = { - "Scene.JWSTTrailLaunch.Renderable.Enabled", - "Scene.JWSTTrailCruise.Renderable.Enabled", - "Scene.JWSTTrailCoRevOrbit.Renderable.Enabled" - } - for _,v in pairs(list) do - openspace.setPropertyValueSingle(v, not openspace.propertyValue(v)) - end + openspace.toggleFade("Scene.JWSTTrailLaunch.Renderable") + openspace.toggleFade("Scene.JWSTTrailCruise.Renderable") + openspace.toggleFade("Scene.JWSTTrailCoRevOrbit.Renderable") ]], Documentation = "Toggle JWST launch, cruise and L2 co-revolving orbit trails, not the Sun trail", GuiPath = "/JWST", diff --git a/data/assets/scene/solarsystem/telescopes/jwst/fieldofview.asset b/data/assets/scene/solarsystem/telescopes/jwst/fieldofview.asset index 95d5117d3d..119342ebdb 100644 --- a/data/assets/scene/solarsystem/telescopes/jwst/fieldofview.asset +++ b/data/assets/scene/solarsystem/telescopes/jwst/fieldofview.asset @@ -30,6 +30,7 @@ local JWSTFov = { GUI = { Name = "JWST Field of View", Path = "/Solar System/Telescopes/JWST", + Focusable = false, Description = [[ The field of view for the James Webb Space Telescope at its current position. ]] diff --git a/data/assets/scene/solarsystem/telescopes/jwst/label.asset b/data/assets/scene/solarsystem/telescopes/jwst/label.asset index 21fe46a65c..567fb8c83c 100644 --- a/data/assets/scene/solarsystem/telescopes/jwst/label.asset +++ b/data/assets/scene/solarsystem/telescopes/jwst/label.asset @@ -23,6 +23,7 @@ local JWSTLabel = { GUI = { Name = "JWST Label", Path = "/Solar System/Telescopes/JWST", + Focusable = false, Description = "Main label for the James Webb Space Telescope." } } diff --git a/data/assets/scene/solarsystem/telescopes/jwst/mission.asset b/data/assets/scene/solarsystem/telescopes/jwst/mission.asset index e1ede5a9ce..00f3fe29c5 100644 --- a/data/assets/scene/solarsystem/telescopes/jwst/mission.asset +++ b/data/assets/scene/solarsystem/telescopes/jwst/mission.asset @@ -1,20 +1,20 @@ local Mission = { Identifier = "JWST", Name = "James Webb Space Telescope", - Image = "https://www.esa.int/var/esa/storage/images/esa_multimedia/images/2016/12/jwst_mission_logo/16561412-4-eng-GB/JWST_mission_logo_pillars.png", + Image = "https://data.openspaceproject.com/missions/jwst/JWST_mission_logo_pillars.png", Description = "The James Webb Space Telescope (sometimes called JWST or Webb) is an orbiting infrared observatory that will complement and extend the discoveries of the Hubble Space Telescope, with longer wavelength coverage and greatly improved sensitivity. The longer wavelengths enable Webb to look much closer to the beginning of time and to hunt for the unobserved formation of the first galaxies, as well as to look inside dust clouds where stars and planetary systems are forming today.", Milestones = { { Name = "Launch", Date = "2021 DEC 25 12:20:00", - Image = "https://webb.nasa.gov/ImagesContent/51775043129_7aeedc5a6d_k.jpg", + Image = "https://data.openspaceproject.com/missions/jwst/51775043129_7aeedc5a6d_k.jpg", Description = "Webb was launched from Arianespace's ELA-3 launch complex at Europe's Spaceport located near Kourou, French Guiana. It is beneficial for launch sites to be located near the equator - the spin of the Earth can help give an additional push. The surface of the Earth at the equator is moving at 1670 km/hr. The James Webb Space Telescope was launched on an Ariane 5 rocket. The launch vehicle and launch site were part of the European Space Agency's contribution to the mission. The Ariane 5 is one of the world's most reliable launch vehicles and was chosen for a combination of reliability (it was the only launch vehicle that met NASA's requirements for launching a mission like Webb) and for the value it brought via our international partnership." }, { Name = "Arrival at L2 orbit", Date = "2022 JAN 24 00:00:00", Description = "When you ask an astronomer about the James Webb Space Telescope's orbit, they'll tell you something that sounds like it came from a science-fiction novel. The Webb won't be orbiting the Earth - instead we will send it almost a million miles out into space to a place called 'L2'. L2 is short-hand for the second Lagrange Point, a wonderful accident of gravity and orbital mechanics, and the perfect place to park the Webb telescope in space. There are five so-called 'Lagrange Points' - areas where gravity from the sun and Earth balance the orbital motion of a satellite. Putting a spacecraft at any of these points allows it to stay in a fixed position relative to the Earth and sun with a minimal amount of energy needed for course correction.", - Image = "https://www.nasa.gov/images/content/463480main_lagrange_point_lg_1.jpg", + Image = "https://data.openspaceproject.com/missions/jwst/463480main_lagrange_point_lg_1.webp", Link = "https://www.nasa.gov/topics/universe/features/webb-l2.html" }, { @@ -25,19 +25,19 @@ local Mission = { Name = "Fine phasing alignment", Date = "2022 MAR 11 00:00:00", Description = "While the purpose of this image was to focus on the bright star at the center for alignment evaluation, Webb's optics and NIRCam are so sensitive that the galaxies and stars seen in the background show up. At this stage of Webb's mirror alignment, known as “fine phasing,” each of the primary mirror segments have been adjusted to produce one unified image of the same star using only the NIRCam instrument. This image of the star, which is called 2MASS J17554042+6551277, uses a red filter to optimize visual contrast.", - Image = "https://www.nasa.gov/sites/default/files/thumbnails/image/telescope_alignment_evaluation_image_labeled.png" + Image = "https://data.openspaceproject.com/missions/jwst/telescope_alignment_evaluation_image_labeled.jpg" }, { Name = "First deep field image released", Date = "2022 JUL 11 14:30:00", Description = "JWST's first science image was released a day early, on July 11, 2022, in an address by the President of the United States, Joe Biden. This deep field image is the highest-resolution and deepest infrared view of our Universe taken to date. The light from these galaxies is gravitationally lensed by the mass of the galaxy cluster SMACS 0723 in the foreground. It causes their light to be warped into beautiful arcs. This image shows SMACS 0723 as it was 4.6 billion years ago, but the background galaxies are much further away. The furthest light in this image has taken over 13 billion years to reach us. This image represents a part of the sky that's so small that it could fit behind a grain of sand on the tip of your finger held at arm's length.", - Image = "https://planetary.s3.amazonaws.com/web/assets/pictures/_2400x2448_crop_center-center_82_line/JWST-First-Deep-Field.jpg.webp", + Image = "https://data.openspaceproject.com/missions/jwst/JWST-First-Deep-Field.jpg.webp", Link = "https://webbtelescope.org/news/first-images/gallery" }, { Name = "Alignment complete", Description = "Alignment of NASA's James Webb Space Telescope is now complete. After full review, the observatory has been confirmed to be capable of capturing crisp, well-focused images with each of its four powerful onboard science instruments. Upon completing the seventh and final stage of telescope alignment, the team held a set of key decision meetings and unanimously agreed that Webb is ready to move forward into its next and final series of preparations, known as science instrument commissioning. This process will take about two months before scientific operations begin in the summer.", - Image = "https://blogs.nasa.gov/webb/wp-content/uploads/sites/326/2022/04/webb_img_sharpness.png", + Image = "https://data.openspaceproject.com/missions/jwst/webb_img_sharpness.png", Date = "2022 APR 28 00:00:00", Link = "https://blogs.nasa.gov/webb/2022/04/28/nasas-webb-in-full-focus-ready-for-instrument-commissioning/" } @@ -59,7 +59,7 @@ local Mission = { { Name = "Sunshield deployment", TimeRange = { Start = "2021 DEC 25 12:50:00", End = "2022 JAN 04 00:00:00" }, - Image = "https://c1.staticflickr.com/5/4573/37594108385_36d5e25c8a_b.jpg", + Image = "https://data.openspaceproject.com/missions/jwst/37594108385_36d5e25c8a_b.jpg", Description = "The sunshield separates the observatory into a warm, sun-facing side (thermal models show the max temperature of the outermost layer is 383K or approximately 230F or 110C), and a cold side (with the coldest layer having a modeled minimum temp of 36K or around -394F or -236C). The five-layer sunshield keeps sunlight from interfering with the sensitive telescope instruments. The telescope operates under 50K (~-370F or ~-223C)" } } @@ -67,9 +67,8 @@ local Mission = { { Name = "Telescope alignment", TimeRange = { Start = "2022 JAN 24 00:00:00", End = "2022 APR 28 00:00:00" }, - Image = "https://blogs.nasa.gov/webb/wp-content/uploads/sites/326/2022/02/alignment_mosaic_compressed-1200x813.png", - Description = "Using the Fine Guidance Sensor, we pointed Webb at a single bright star and demonstrated that the observatory could acquire and lock onto targets, and we took data mainly with NIRCam. But because the primary mirror segments had yet to be aligned to work as a single mirror, there were distorted images of the same single target star. We then embarked on the long process of aligning all the telescope optics, beginning with identifying which primary mirror segment went with which image by moving each segment one at a time and ended a few months later with all the segments aligned as one and the secondary mirror aligned optimally.", - Link = "https://blogs.nasa.gov/webb/wp-content/uploads/sites/326/2022/02/SegmentAlignment.gif" + Image = "https://data.openspaceproject.com/missions/jwst/alignment_mosaic_compressed-1200x813.png", + Description = "Using the Fine Guidance Sensor, we pointed Webb at a single bright star and demonstrated that the observatory could acquire and lock onto targets, and we took data mainly with NIRCam. But because the primary mirror segments had yet to be aligned to work as a single mirror, there were distorted images of the same single target star. We then embarked on the long process of aligning all the telescope optics, beginning with identifying which primary mirror segment went with which image by moving each segment one at a time and ended a few months later with all the segments aligned as one and the secondary mirror aligned optimally." }, { Name = "Science instrument commissioning", diff --git a/data/assets/scene/solarsystem/telescopes/jwst/targets/hudf.asset b/data/assets/scene/solarsystem/telescopes/jwst/targets/hudf.asset index f3e60a457c..12193c48d7 100644 --- a/data/assets/scene/solarsystem/telescopes/jwst/targets/hudf.asset +++ b/data/assets/scene/solarsystem/telescopes/jwst/targets/hudf.asset @@ -77,12 +77,10 @@ asset.onInitialize(function() openspace.addScreenSpaceRenderable(HUDFImage) openspace.addSceneGraphNode(HUDFPosition) - openspace.addSceneGraphNode(HUDFImage) openspace.addSceneGraphNode(HUDFJWSTLine) end) asset.onDeinitialize(function() openspace.removeSceneGraphNode(HUDFPosition) - openspace.removeSceneGraphNode(HUDFImage) openspace.removeSceneGraphNode(HUDFJWSTLine) openspace.removeScreenSpaceRenderable(HUDFImage) diff --git a/data/assets/scene/solarsystem/telescopes/jwst/trail.asset b/data/assets/scene/solarsystem/telescopes/jwst/trail.asset index 928564a9e1..fa7d4c6758 100644 --- a/data/assets/scene/solarsystem/telescopes/jwst/trail.asset +++ b/data/assets/scene/solarsystem/telescopes/jwst/trail.asset @@ -36,6 +36,7 @@ local JWSTTrailLaunch = { GUI = { Name = "JWST Launch Trail", Path = "/Solar System/Telescopes/JWST/Trails", + Focusable = false, Description = "James Webb Space Telescope Launch Trail relative to Earth IAU." } } @@ -66,6 +67,7 @@ local JWSTTrailCruise = { GUI = { Name = "JWST Cruise Trail", Path = "/Solar System/Telescopes/JWST/Trails", + Focusable = false, Description = "James Webb Space Telescope Cruise Trail relative to Earth." } } @@ -97,6 +99,7 @@ local JWSTTrailOrbit = { GUI = { Name = "JWST Orbit Trail", Path = "/Solar System/Telescopes/JWST/Trails", + Focusable = false, Description = "James Webb Space Telescope Orbit Trail relative to L2." } } @@ -127,6 +130,7 @@ local JWSTTrailCoRevOrbit = { GUI = { Name = "JWST L2 Co-revolving Orbit Trail", Path = "/Solar System/Telescopes/JWST/Trails", + Focusable = false, Description = "James Webb Space Telescope Orbit Trail that Co-revolves with L2." } } @@ -155,6 +159,7 @@ local JWSTSunTrail = { GUI = { Name = "JWST Sun Trail", Path = "/Solar System/Telescopes/JWST/Trails", + Focusable = false, Description = "James Webb Space Telescope Trail relative to the Sun." } } diff --git a/data/assets/scene/solarsystem/telescopes/jwst/transforms.asset b/data/assets/scene/solarsystem/telescopes/jwst/transforms.asset index 56fa1265b7..d5097f78a1 100644 --- a/data/assets/scene/solarsystem/telescopes/jwst/transforms.asset +++ b/data/assets/scene/solarsystem/telescopes/jwst/transforms.asset @@ -43,6 +43,7 @@ local JWSTPosition = { GUI = { Name = "JWST Position", Path = "/Solar System/Telescopes/JWST", + Focusable = false, Hidden = true } } @@ -63,6 +64,7 @@ local JWSTRotation = { GUI = { Name = "JWST Rotation", Path = "/Solar System/Telescopes/JWST", + Focusable = false, Hidden = true } } diff --git a/data/assets/scene/solarsystem/telescopes/jwst/viewingband.asset b/data/assets/scene/solarsystem/telescopes/jwst/viewingband.asset index 9177158b10..a616d3277e 100644 --- a/data/assets/scene/solarsystem/telescopes/jwst/viewingband.asset +++ b/data/assets/scene/solarsystem/telescopes/jwst/viewingband.asset @@ -41,6 +41,7 @@ local JWSTBand = { GUI = { Name = "JWST Safe Viewing Band", Path = "/Solar System/Telescopes/JWST", + Focusable = false, Description = [[ The safe viewing band for the James Webb Space Telescope at its current position. ]] diff --git a/data/assets/util/calibration.asset b/data/assets/util/calibration.asset new file mode 100644 index 0000000000..0e2a879a22 --- /dev/null +++ b/data/assets/util/calibration.asset @@ -0,0 +1,221 @@ +local textures = asset.resource({ + Name = "Calibration Images", + Type = "HttpSynchronization", + Identifier = "calibration_images", + Version = 1 +}) + +local Distance = 1000 +local Size = 1000 + + +local Center = { + Identifier = "Calibration", + GUI = { + Name = "Calibration", + Description = "The centerpoint of the calibration cube", + Path = "/Calibration" + } +} + +local Front = { + Identifier = "Calibration_Front", + Parent = Center.Identifier, + Transform = { + Translation = { + Type = "StaticTranslation", + Position = { 0, Distance, 0 } + }, + Rotation = { + Type = "StaticRotation", + Rotation = { math.pi / 2.0, 0.0, 0.0 } + } + }, + Renderable = { + Type = "RenderablePlaneImageLocal", + Enabled = asset.enabled, + Size = Size, + Origin = "Center", + Texture = textures .. "test-pattern-0.png" + }, + GUI = { + Name = "Calibration (Front)", + Description = "The front face of the calibration cube", + Path = "/Calibration" + } +} + +local Right = { + Identifier = "Calibration_Right", + Parent = Center.Identifier, + Transform = { + Translation = { + Type = "StaticTranslation", + Position = { Distance, 0, 0 } + }, + Rotation = { + Type = "StaticRotation", + Rotation = { math.pi / 2.0, 0.0, -math.pi / 2.0 } + } + }, + Renderable = { + Type = "RenderablePlaneImageLocal", + Enabled = asset.enabled, + Size = Size, + Origin = "Center", + Texture = textures .. "test-pattern-1.png" + }, + GUI = { + Name = "Calibration (Right)", + Description = "The right face of the calibration cube", + Path = "/Calibration" + } +} + +local Back = { + Identifier = "Calibration_Back", + Parent = Center.Identifier, + Transform = { + Translation = { + Type = "StaticTranslation", + Position = { 0, -Distance, 0 } + }, + Rotation = { + Type = "StaticRotation", + Rotation = { -math.pi / 2.0, math.pi, 0.0 } + } + }, + Renderable = { + Type = "RenderablePlaneImageLocal", + Enabled = asset.enabled, + Size = Size, + Origin = "Center", + Texture = textures .. "test-pattern-2.png" + }, + GUI = { + Name = "Calibration (Back)", + Description = "The back face of the calibration cube", + Path = "/Calibration" + } +} + +local Left = { + Identifier = "Calibration_Left", + Parent = Center.Identifier, + Transform = { + Translation = { + Type = "StaticTranslation", + Position = { -Distance, 0, 0 } + }, + Rotation = { + Type = "StaticRotation", + Rotation = { math.pi / 2.0, 0.0, math.pi / 2.0 } + } + }, + Renderable = { + Type = "RenderablePlaneImageLocal", + Enabled = asset.enabled, + Size = Size, + Origin = "Center", + Texture = textures .. "test-pattern-3.png" + }, + GUI = { + Name = "Calibration (Left)", + Description = "The left face of the calibration cube", + Path = "/Calibration" + } +} + +local Top = { + Identifier = "Calibration_Top", + Parent = Center.Identifier, + Transform = { + Translation = { + Type = "StaticTranslation", + Position = { 0, 0, Distance } + }, + Rotation = { + Type = "StaticRotation", + Rotation = { 0.0, math.pi, -math.pi } + } + }, + Renderable = { + Type = "RenderablePlaneImageLocal", + Enabled = asset.enabled, + Size = Size, + Origin = "Center", + Texture = textures .. "test-pattern-4.png" + }, + GUI = { + Name = "Calibration (Top)", + Description = "The top face of the calibration cube", + Path = "/Calibration" + } +} + +local Bottom = { + Identifier = "Calibration_Bottom", + Parent = Center.Identifier, + Transform = { + Translation = { + Type = "StaticTranslation", + Position = { 0, 0, -Distance } + }, + Rotation = { + Type = "StaticRotation", + Rotation = { 0.0, 0.0, 0.0 } + } + }, + Renderable = { + Type = "RenderablePlaneImageLocal", + Enabled = asset.enabled, + Size = Size, + Origin = "Center", + Texture = textures .. "test-pattern-5.png" + }, + GUI = { + Name = "Calibration (Bottom)", + Description = "The bottom face of the calibration cube", + Path = "/Calibration" + } +} + + +asset.onInitialize(function() + openspace.addSceneGraphNode(Center) + openspace.addSceneGraphNode(Left) + openspace.addSceneGraphNode(Right) + openspace.addSceneGraphNode(Front) + openspace.addSceneGraphNode(Back) + openspace.addSceneGraphNode(Top) + openspace.addSceneGraphNode(Bottom) +end) + +asset.onDeinitialize(function() + openspace.removeSceneGraphNode(Bottom) + openspace.removeSceneGraphNode(Top) + openspace.removeSceneGraphNode(Back) + openspace.removeSceneGraphNode(Front) + openspace.removeSceneGraphNode(Right) + openspace.removeSceneGraphNode(Left) + openspace.removeSceneGraphNode(Center) +end) + +asset.export(Center) +asset.export(Left) +asset.export(Right) +asset.export(Front) +asset.export(Back) +asset.export(Top) +asset.export(Bottom) + + + +asset.meta = { + Name = "Calibrator", + Description = [[A cube that can be used to verify calibration in a complicated display + environment]], + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/data/assets/util/joysticks/any-joystick.asset b/data/assets/util/joysticks/any-joystick.asset index 9e9ef66a9e..94033b38e0 100644 --- a/data/assets/util/joysticks/any-joystick.asset +++ b/data/assets/util/joysticks/any-joystick.asset @@ -1,4 +1,3 @@ -local propertyHelper = asset.require("../property_helper") local joystickHelper = asset.require("./joystick_helper") diff --git a/data/assets/util/joysticks/microsoft-xbox-360-pad.asset b/data/assets/util/joysticks/microsoft-xbox-360-pad.asset index 528c6b18f9..443216b31e 100644 --- a/data/assets/util/joysticks/microsoft-xbox-360-pad.asset +++ b/data/assets/util/joysticks/microsoft-xbox-360-pad.asset @@ -1,4 +1,3 @@ -local propertyHelper = asset.require("../property_helper") local joystickHelper = asset.require("./joystick_helper") @@ -119,19 +118,19 @@ asset.onInitialize(function() openspace.navigation.bindJoystickButton( name, controller.A, - propertyHelper.invert("NavigationHandler.OrbitalNavigator.Friction.RotationalFriction"), + [[openspace.invertBooleanProperty("NavigationHandler.OrbitalNavigator.Friction.RotationalFriction")]], "Toggle rotational friction" ) openspace.navigation.bindJoystickButton( name, controller.B, - propertyHelper.invert("NavigationHandler.OrbitalNavigator.Friction.ZoomFriction"), + [[openspace.invertBooleanProperty("NavigationHandler.OrbitalNavigator.Friction.ZoomFriction")]], "Toggle zoom friction" ) openspace.navigation.bindJoystickButton( name, controller.Y, - propertyHelper.invert("NavigationHandler.OrbitalNavigator.Friction.RollFriction"), + [[openspace.invertBooleanProperty("NavigationHandler.OrbitalNavigator.Friction.RollFriction")]], "Toggle roll friction" ) diff --git a/data/assets/util/joysticks/ps4.asset b/data/assets/util/joysticks/ps4.asset index f8696079e8..e59f492657 100644 --- a/data/assets/util/joysticks/ps4.asset +++ b/data/assets/util/joysticks/ps4.asset @@ -1,4 +1,3 @@ -local propertyHelper = asset.require("../property_helper") local joystickHelper = asset.require("./joystick_helper") @@ -121,19 +120,19 @@ asset.onInitialize(function() openspace.navigation.bindJoystickButton( name, controller.Cross, - propertyHelper.invert("NavigationHandler.OrbitalNavigator.Friction.RotationalFriction"), + [[openspace.invertBooleanProperty("NavigationHandler.OrbitalNavigator.Friction.RotationalFriction")]], "Toggle rotational friction" ) openspace.navigation.bindJoystickButton( name, controller.Circle, - propertyHelper.invert("NavigationHandler.OrbitalNavigator.Friction.ZoomFriction"), + [[openspace.invertBooleanProperty("NavigationHandler.OrbitalNavigator.Friction.ZoomFriction")]], "Toggle zoom friction" ) openspace.navigation.bindJoystickButton( name, controller.Triangle, - propertyHelper.invert("NavigationHandler.OrbitalNavigator.Friction.RollFriction"), + [[openspace.invertBooleanProperty("NavigationHandler.OrbitalNavigator.Friction.RollFriction")]], "Toggle roll friction" ) diff --git a/data/assets/util/joysticks/ps5.asset b/data/assets/util/joysticks/ps5.asset index f2c55bc0e0..a61fa4f78c 100644 --- a/data/assets/util/joysticks/ps5.asset +++ b/data/assets/util/joysticks/ps5.asset @@ -1,4 +1,3 @@ -local propertyHelper = asset.require("../property_helper") local joystickHelper = asset.require("./joystick_helper") @@ -124,19 +123,19 @@ asset.onInitialize(function() openspace.navigation.bindJoystickButton( name, controller.Cross, - propertyHelper.invert("NavigationHandler.OrbitalNavigator.Friction.RotationalFriction"), + [[openspace.invertBooleanProperty("NavigationHandler.OrbitalNavigator.Friction.RotationalFriction")]], "Toggle rotational friction" ) openspace.navigation.bindJoystickButton( name, controller.Circle, - propertyHelper.invert("NavigationHandler.OrbitalNavigator.Friction.ZoomFriction"), + [[openspace.invertBooleanProperty("NavigationHandler.OrbitalNavigator.Friction.ZoomFriction")]], "Toggle zoom friction" ) openspace.navigation.bindJoystickButton( name, controller.Triangle, - propertyHelper.invert("NavigationHandler.OrbitalNavigator.Friction.RollFriction"), + [[openspace.invertBooleanProperty("NavigationHandler.OrbitalNavigator.Friction.RollFriction")]], "Toggle roll friction" ) diff --git a/data/assets/util/joysticks/space-mouse-compact-wireless.asset b/data/assets/util/joysticks/space-mouse-compact-wireless.asset index 3ef46d306c..46d4b6578a 100644 --- a/data/assets/util/joysticks/space-mouse-compact-wireless.asset +++ b/data/assets/util/joysticks/space-mouse-compact-wireless.asset @@ -1,4 +1,3 @@ -local propertyHelper = asset.require("../property_helper") local joystickHelper = asset.require("./joystick_helper") diff --git a/data/assets/util/joysticks/space-mouse-compact.asset b/data/assets/util/joysticks/space-mouse-compact.asset index 77b911effe..d63d3e41c2 100644 --- a/data/assets/util/joysticks/space-mouse-compact.asset +++ b/data/assets/util/joysticks/space-mouse-compact.asset @@ -1,4 +1,3 @@ -local propertyHelper = asset.require("../property_helper") local joystickHelper = asset.require("./joystick_helper") diff --git a/data/assets/util/joysticks/space-mouse-enterprise-wireless.asset b/data/assets/util/joysticks/space-mouse-enterprise-wireless.asset index 279a8c3cd2..de7982cfe9 100644 --- a/data/assets/util/joysticks/space-mouse-enterprise-wireless.asset +++ b/data/assets/util/joysticks/space-mouse-enterprise-wireless.asset @@ -1,4 +1,3 @@ -local propertyHelper = asset.require("../property_helper") local joystickHelper = asset.require("./joystick_helper") diff --git a/data/assets/util/joysticks/space-mouse-enterprise.asset b/data/assets/util/joysticks/space-mouse-enterprise.asset index b3ee78bf1c..c9f5dbf2d1 100644 --- a/data/assets/util/joysticks/space-mouse-enterprise.asset +++ b/data/assets/util/joysticks/space-mouse-enterprise.asset @@ -1,4 +1,3 @@ -local propertyHelper = asset.require("../property_helper") local joystickHelper = asset.require("./joystick_helper") diff --git a/data/assets/util/joysticks/xbox-wireless.asset b/data/assets/util/joysticks/xbox-wireless.asset index 699dc1eb6a..0c7579515d 100644 --- a/data/assets/util/joysticks/xbox-wireless.asset +++ b/data/assets/util/joysticks/xbox-wireless.asset @@ -1,4 +1,3 @@ -local propertyHelper = asset.require("../property_helper") local joystickHelper = asset.require("./joystick_helper") @@ -119,19 +118,19 @@ asset.onInitialize(function() openspace.navigation.bindJoystickButton( name, controller.A, - propertyHelper.invert("NavigationHandler.OrbitalNavigator.Friction.RotationalFriction"), + [[openspace.invertBooleanProperty("NavigationHandler.OrbitalNavigator.Friction.RotationalFriction")]], "Toggle rotational friction" ) openspace.navigation.bindJoystickButton( name, controller.B, - propertyHelper.invert("NavigationHandler.OrbitalNavigator.Friction.ZoomFriction"), + [[openspace.invertBooleanProperty("NavigationHandler.OrbitalNavigator.Friction.ZoomFriction")]], "Toggle zoom friction" ) openspace.navigation.bindJoystickButton( name, controller.Y, - propertyHelper.invert("NavigationHandler.OrbitalNavigator.Friction.RollFriction"), + [[openspace.invertBooleanProperty("NavigationHandler.OrbitalNavigator.Friction.RollFriction")]], "Toggle roll friction" ) diff --git a/data/assets/util/joysticks/xbox.asset b/data/assets/util/joysticks/xbox.asset index a31b8cb5db..46a4bb6b16 100644 --- a/data/assets/util/joysticks/xbox.asset +++ b/data/assets/util/joysticks/xbox.asset @@ -1,4 +1,3 @@ -local propertyHelper = asset.require("../property_helper") local joystickHelper = asset.require("./joystick_helper") @@ -119,19 +118,19 @@ asset.onInitialize(function() openspace.navigation.bindJoystickButton( name, controller.A, - propertyHelper.invert("NavigationHandler.OrbitalNavigator.Friction.RotationalFriction"), + [[openspace.invertBooleanProperty("NavigationHandler.OrbitalNavigator.Friction.RotationalFriction")]], "Toggle rotational friction" ) openspace.navigation.bindJoystickButton( name, controller.B, - propertyHelper.invert("NavigationHandler.OrbitalNavigator.Friction.ZoomFriction"), + [[openspace.invertBooleanProperty("NavigationHandler.OrbitalNavigator.Friction.ZoomFriction")]], "Toggle zoom friction" ) openspace.navigation.bindJoystickButton( name, controller.Y, - propertyHelper.invert("NavigationHandler.OrbitalNavigator.Friction.RollFriction"), + [[openspace.invertBooleanProperty("NavigationHandler.OrbitalNavigator.Friction.RollFriction")]], "Toggle roll friction" ) diff --git a/data/assets/util/property_helper.asset b/data/assets/util/property_helper.asset deleted file mode 100644 index 99f059b6a6..0000000000 --- a/data/assets/util/property_helper.asset +++ /dev/null @@ -1,50 +0,0 @@ --- Function that returns the string that inverts the fully qualified boolean property 'property' -function invert(prop) - local escaped_property = [["]] .. prop .. [["]] - return "openspace.setPropertyValueSingle(" .. escaped_property .. ", not openspace.propertyValue(" .. escaped_property .. "))" -end - --- Function that returns the string that increments the 'property' by the 'value' -function increment(prop, value) - local v = value or 1 - local escaped_property = [["]] .. prop .. [["]] - return "openspace.setPropertyValueSingle(" .. escaped_property .. ", openspace.propertyValue(" .. escaped_property .. ") + " .. v .. ")" -end - --- Function that returns the string that decrements the 'property' by the 'value' -function decrement(prop, value) - return increment(prop, -value) -end - -function fade(prop, value, duration) - assert(type(prop) == "string", "prop must be a number") - assert(type(duration) == "number", "duration must be a number") - - local escaped_property = [["]] .. prop .. [["]] - return "openspace.setPropertyValueSingle(" .. escaped_property ..", " .. tostring(value) .. ", " .. tostring(duration) .. ")" -end - -function fadeOut(prop, duration) - return fade(prop, 0.0, duration) -end - -function fadeIn(prop, duration) - return fade(prop, 1.0, duration) -end - -function fadeInOut(prop, duration) - assert(type(prop) == "string", "prop must be a number") - assert(type(duration) == "number", "duration must be a number") - - local escaped_property = [["]] .. prop .. [["]] - -- If the value is > 0.5 fade out, otherwise fade in - return "local v = openspace.propertyValue(" .. escaped_property .. ") if v <= 0.5 then " .. fadeIn(prop, duration) .. " else " .. fadeOut(prop, duration) .. " end" -end - -asset.export("invert", invert) -asset.export("increment", increment) -asset.export("decrement", decrement) -asset.export("fade", fade) -asset.export("fadeIn", fadeIn) -asset.export("fadeOut", fadeOut) -asset.export("fadeInOut", fadeInOut) diff --git a/data/assets/util/renderable_helper.asset b/data/assets/util/renderable_helper.asset deleted file mode 100644 index 72e32f1cf4..0000000000 --- a/data/assets/util/renderable_helper.asset +++ /dev/null @@ -1,16 +0,0 @@ -local propertyHelper = asset.require("./property_helper") - - - --- Function that returns the string that enables/disables the renderable 'renderable' -function toggle(renderable) - return propertyHelper.invert(renderable .. ".Renderable.Enabled") -end - --- Function that returns the string that sets the enabled property of to -function setEnabled(renderable, enabled) - return [[openspace.setPropertyValue("]] .. renderable .. [[.Renderable.Enabled", ]] .. (enabled and "true" or "false") .. ")" -end - -asset.export("toggle", toggle) -asset.export("setEnabled", setEnabled) diff --git a/data/assets/util/static_server.asset b/data/assets/util/static_server.asset index b6a4c39804..23b02f702f 100644 --- a/data/assets/util/static_server.asset +++ b/data/assets/util/static_server.asset @@ -1,4 +1,4 @@ -local BackendHash = "7ca0a34e9c4c065b7bfad0623db0e322bf3e0af9" +local BackendHash = "0f2543a69aa6c1ecd15892c43c5196d4fdc55b8f" local backend = asset.resource({ Identifier = "WebGuiBackend", diff --git a/data/assets/util/webgui.asset b/data/assets/util/webgui.asset index a382a4a524..035b835f92 100644 --- a/data/assets/util/webgui.asset +++ b/data/assets/util/webgui.asset @@ -3,22 +3,49 @@ local guiCustomization = asset.require("customization/gui") --- Select which commit hashes to use for the frontend and backend -local frontendHash = "1e64af3b19764af15ad844dec543b1fffec99fe9" +-- Select which commit hashes to use for the UI frontend +local frontendHash = "baabd171ecbe61b2758970a2cdafb43fbcd1a23b" + +-- The name of the file to download from the server +local frontendFile = "frontend.zip" local frontend = asset.resource({ Identifier = "WebGuiFrontend", Name = "Web Gui Frontend", Type = "UrlSynchronization", - Url = "http://data.openspaceproject.com/files/webgui/frontend/" .. frontendHash .. "/frontend.zip" + Url = "http://data.openspaceproject.com/files/webgui/frontend/" .. frontendHash .. "/" .. frontendFile +}) + + +local showcomposerHash = "9071d8bc80d16dc1e081017e02297915563f0a64" +local showcomposerFile = "showcomposer.zip" + +local showcomposer = asset.resource({ + Identifier = "WebGuiShowComposer", + Name = "Web Gui ShowComposer", + Type = "UrlSynchronization", + Url = "http://data.openspaceproject.com/files/webgui/showcomposer/" .. showcomposerHash .. "/" .. showcomposerFile +}) + + +local maps = asset.resource({ + Identifier = "userinterface_maps", + Name = "Userinterface Maps", + Type = "HttpSynchronization", + Version = 1 }) asset.onInitialize(function() -- Unzip the frontend bundle - local dest = frontend .. "frontend" - if not openspace.directoryExists(dest) then - openspace.unzipFile(frontend .. "frontend.zip", dest, true) + local destFrontend = frontend .. "frontend" + if not openspace.directoryExists(destFrontend) then + openspace.unzipFile(frontend .. frontendFile, destFrontend, true) + end + + local destShowcomposer = showcomposer .. "showcomposer" + if not openspace.directoryExists(destShowcomposer) then + openspace.unzipFile(showcomposer .. showcomposerFile, destShowcomposer, true) end -- Disable the server, add production gui endpoint, and restart server. @@ -31,14 +58,28 @@ asset.onInitialize(function() openspace.setPropertyValueSingle("Modules.WebGui.ServerProcessEnabled", false) local directories = openspace.propertyValue("Modules.WebGui.Directories") - directories[#directories + 1] = "frontend" + directories[#directories + 1] = "gui" directories[#directories + 1] = frontend .. "frontend" -- Add user directory for webpanels directories[#directories + 1] = "webpanels" directories[#directories + 1] = openspace.absPath("${USER_WEBPANELS}") + -- Add user directories for showcompower + directories[#directories + 1] = "showcomposer" + directories[#directories + 1] = showcomposer .. "showcomposer" + directories[#directories + 1] = "showcomposer/hub" + directories[#directories + 1] = showcomposer .. "showcomposer" + directories[#directories + 1] = "showcomposer/uploads" + directories[#directories + 1] = openspace.absPath("${USER_SHOWCOMPOSER_UPLOADS}") + directories[#directories + 1] = "showcomposer/projects" + directories[#directories + 1] = openspace.absPath("${USER_SHOWCOMPOSER_PROJECTS}") + + -- Add asset folders + directories[#directories + 1] = "assets/maps" + directories[#directories + 1] = maps + openspace.setPropertyValueSingle("Modules.WebGui.Directories", directories) - openspace.setPropertyValueSingle("Modules.WebGui.DefaultEndpoint", "frontend") + openspace.setPropertyValueSingle("Modules.WebGui.DefaultEndpoint", "gui") openspace.setPropertyValueSingle("Modules.WebGui.ServerProcessEnabled", enabled) -- The GUI contains date and simulation increment, @@ -51,6 +92,18 @@ asset.onInitialize(function() openspace.setPropertyValueSingle("Dashboard.SimulationIncrement.Enabled", false) end end + + -- Set the GUI default endpoint + local port = openspace.propertyValue("Modules.WebGui.Port") + -- As a developer, you can manually serve the webgui from port 4690 + -- with the command `npm start` in the web gui repository + if guiCustomization.webguiDevelopmentMode then + port = 4690 + end + openspace.setPropertyValueSingle( + "Modules.CefWebGui.GuiUrl", + "http://127.0.0.1:" .. port .. "/gui" + ) end) asset.onDeinitialize(function() @@ -75,23 +128,6 @@ asset.onDeinitialize(function() --openspace.setPropertyValueSingle("Modules.WebGui.Directories", newDirectories) end) -function setCefRoute(route) - local port = openspace.propertyValue("Modules.WebGui.Port") - -- As a developer, you can manually serve the webgui from port 4690 - -- with the command `npm start` in the web gui repository - if guiCustomization.webguiDevelopmentMode then - port = 4690 - end - openspace.setPropertyValueSingle( - "Modules.CefWebGui.GuiUrl", - "http://127.0.0.1:" .. port .. "/frontend/#/" .. route - ) -end - -asset.export("setCefRoute", setCefRoute) - - - asset.meta = { Name = "WebGUI", Author = "OpenSpace Team", diff --git a/data/profiles/asteroids.profile b/data/profiles/asteroids.profile index 251a241ab2..b4f8ef1704 100644 --- a/data/profiles/asteroids.profile +++ b/data/profiles/asteroids.profile @@ -59,7 +59,7 @@ ], "meta": { "author": "OpenSpace Team", - "description": "This profile shows approximately 936,000 asteroids from the JPL Horizons Small-Body Database (SBDB). Included in this profile (and defined on our wiki): Amor Asteroids, Apollo Asteroids, Aten Asteroids, Atira Asteroids, Centaur Asteroids, Chiron-Type Comets, Encke-Type Comets, Halley-Type Comets, Inner Main Asteroid Belt Asteroids, Jupiter Family Comets, Jupiter Trojan Asteroids, Main Asteroid Belt Asteroids, Mars-Crossing Asteroids, Outer Main Asteroid Belt Asteroids, Potentially Hazardous Asteroids (PHAs), and Trans-Neptunian Asteroids", + "description": "This profile shows approximately 936,000 asteroids from the JPL Horizons Small-Body Database (SBDB). Included in this profile (and defined on our wiki): Amor Asteroids, Apollo Asteroids, Aten Asteroids, Atira Asteroids, Centaur Asteroids, Chiron-Type Comets, Encke-Type Comets, Halley-Type Comets, Inner Main Asteroid Belt Asteroids, Jupiter Family Comets, Jupiter Trojan Asteroids, Main Asteroid Belt Asteroids, Mars-Crossing Asteroids, Outer Main Asteroid Belt Asteroids, Potentially Hazardous Asteroids (PHAs), and Trans-Neptunian Asteroids.", "license": "MIT License", "name": "Asteroids", "url": "https://www.openspaceproject.com", @@ -164,6 +164,6 @@ }, "version": { "major": 1, - "minor": 2 + "minor": 4 } } \ No newline at end of file diff --git a/data/profiles/calibrator.profile b/data/profiles/calibrator.profile new file mode 100644 index 0000000000..472a48632f --- /dev/null +++ b/data/profiles/calibrator.profile @@ -0,0 +1,36 @@ +{ + "assets": [ + "base_blank", + "util/calibration" + ], + "camera": { + "aim": "Calibration_Front", + "anchor": "Calibration", + "frame": "Calibration", + "position": { + "x": 0.5, + "y": 0.5, + "z": 0.5 + }, + "type": "setNavigationState" + }, + "meta": { + "author": "OpenSpace Team", + "description": "This profile places the camera in the inside of a calibration cube. This profile can be used to verify that a display environment is set up correctly. If a setup is correct, the different windows/viewports should show the correct parts of the surrounding cube accurately and withou any unwanted distortion.", + "license": "MIT license", + "name": "Calibration", + "url": "https://openspaceproject.com", + "version": "1.0" + }, + "properties": [ + { + "name": "NavigationHandler.OrbitalNavigator.LimitZoom.EnableMinimumAllowedDistance", + "type": "setPropertyValueSingle", + "value": "false" + } + ], + "version": { + "major": 1, + "minor": 4 + } +} \ No newline at end of file diff --git a/data/profiles/default.profile b/data/profiles/default.profile index a10d674c90..e52a17d09f 100644 --- a/data/profiles/default.profile +++ b/data/profiles/default.profile @@ -4,7 +4,8 @@ "base_keybindings", "events/toggle_sun", "scene/solarsystem/planets/earth/earth", - "scene/solarsystem/planets/earth/satellites/satellites" + "scene/solarsystem/planets/earth/satellites/satellites", + "scene/solarsystem/planets/earth/noaa-sos/overlays/latlon_grid-white" ], "camera": { "altitude": 17000000.0, @@ -59,7 +60,7 @@ ], "meta": { "author": "OpenSpace Team", - "description": "Default OpenSpace Profile. Adds Earth satellites not contained in other profiles", + "description": "Default OpenSpace Profile. Adds Earth satellites not contained in other profiles.", "license": "MIT License", "name": "Default", "url": "https://www.openspaceproject.com", @@ -67,17 +68,23 @@ }, "properties": [ { - "name": "{earth_satellites}.Renderable.Enabled", + "name": "{earth_satellites~space_stations}.Renderable.Enabled", "type": "setPropertyValue", "value": "false" + }, + { + "name": "Scene.Earth.Renderable.Layers.Overlays.noaa-sos-overlays-latlon_grid-white.Enabled", + "type": "setPropertyValueSingle", + "value": "false" } ], "time": { + "is_paused": false, "type": "relative", "value": "-1d" }, "version": { "major": 1, - "minor": 1 + "minor": 4 } } diff --git a/data/profiles/eclipse.profile b/data/profiles/eclipse.profile index 4efef08434..305f7043e5 100644 --- a/data/profiles/eclipse.profile +++ b/data/profiles/eclipse.profile @@ -36,7 +36,6 @@ 315360000.0, 630720000.0 ], - "keybindings": [], "mark_nodes": [ "Earth", "Moon", @@ -45,9 +44,9 @@ ], "meta": { "author": "OpenSpace Team", - "description": "OpenSpace profile to highlight solar eclipses on the Earth from 1900 to 2100", + "description": "OpenSpace profile to highlight solar eclipses on the Earth from 1900 to 2100.", "license": "MIT License", - "name": "Default", + "name": "Eclipse", "url": "https://www.openspaceproject.com", "version": "1.0" }, @@ -64,11 +63,12 @@ } ], "time": { + "is_paused": false, "type": "relative", "value": "-1d" }, "version": { "major": 1, - "minor": 1 + "minor": 4 } } diff --git a/data/profiles/empty.profile b/data/profiles/empty.profile index da68f0065a..b4af349903 100644 --- a/data/profiles/empty.profile +++ b/data/profiles/empty.profile @@ -22,7 +22,6 @@ "delta_times": [ 1.0 ], - "mark_nodes": [], "meta": { "author": "OpenSpace Team", "description": "An empty profile, without anything special at all.", @@ -32,11 +31,12 @@ "version": "1.0" }, "time": { + "is_paused": false, "type": "relative", "value": "-1d" }, "version": { "major": 1, - "minor": 0 + "minor": 4 } } \ No newline at end of file diff --git a/data/profiles/missions/apollo.profile b/data/profiles/missions/apollo.profile index 0714b6309b..82cd510f83 100644 --- a/data/profiles/missions/apollo.profile +++ b/data/profiles/missions/apollo.profile @@ -53,7 +53,7 @@ }, { "action": "os.apollo.FocusEarth", - "key": "Home" + "key": "HOME" }, { "action": "os.apollo.FocusMoon", @@ -82,12 +82,15 @@ ], "meta": { "author": "OpenSpace Team", - "description": "This profile contains all the apollo assets in openspace. Apollo 8,11,17 and some associated materials. ", + "description": "This profile contains all the apollo assets in OpenSpace. Apollo 8,11,17 and some associated materials.", "license": "MIT License", "name": "Apollo", "url": "https://www.openspaceproject.com", "version": "1.0" }, + "panel_visibility": { + "mission": true + }, "properties": [ { "name": "NavigationHandler.OrbitalNavigator.LimitZoom.MinimumAllowedDistance", @@ -101,11 +104,12 @@ } ], "time": { + "is_paused": false, "type": "absolute", "value": "1968-12-21T12:51:51" }, "version": { "major": 1, - "minor": 1 + "minor": 4 } } diff --git a/data/profiles/missions/artemis.profile b/data/profiles/missions/artemis.profile index 103fcab6ec..11c813bfb6 100644 --- a/data/profiles/missions/artemis.profile +++ b/data/profiles/missions/artemis.profile @@ -12,19 +12,19 @@ "aim": "", "anchor": "ArtemisModel", "frame": "Root", - "yaw": -0.003474, - "pitch": 0.008681, - "type": "setNavigationState", + "pitch": 0.008681, "position": { "x": 364.907409, "y": -65.898746, "z": 361.510673 }, + "type": "setNavigationState", "up": { "x": -0.128611, - "y": 0.944590, + "y": 0.94459, "z": 0.302006 - } + }, + "yaw": -0.003474 }, "delta_times": [ 1.0, @@ -56,15 +56,18 @@ ], "meta": { "author": "OpenSpace Team", - "description": "Artemis Profile. Adds the Orion capsule (Artemis-1) model with an estimated trajectery", + "description": "Artemis Profile. Adds the Orion capsule (Artemis-1) model with its trajectery.", "license": "MIT License", "name": "Artemis", "url": "https://www.openspaceproject.com", "version": "1.0" }, + "panel_visibility": { + "mission": true + }, "properties": [ { - "name": "{earth_satellites}.Renderable.Enabled", + "name": "{earth_satellites~space_stations}.Renderable.Enabled", "type": "setPropertyValue", "value": "false" }, @@ -95,11 +98,12 @@ } ], "time": { + "is_paused": false, "type": "absolute", "value": "2022-11-21T12:00:00" }, "version": { "major": 1, - "minor": 1 + "minor": 4 } } diff --git a/data/profiles/missions/bepicolombo.profile b/data/profiles/missions/bepicolombo.profile index 6cef837a3c..d00a7bcc97 100644 --- a/data/profiles/missions/bepicolombo.profile +++ b/data/profiles/missions/bepicolombo.profile @@ -43,12 +43,15 @@ ], "meta": { "author": "OpenSpace Team", - "description": "Default OpenSpace Profile. Adds Earth satellites not contained in other profiles", + "description": "A profile showing the model and trajectory of ESA's BepiColombo mission to Mercury.", "license": "MIT License", - "name": "Default", + "name": "BepiColombo", "url": "https://www.openspaceproject.com", "version": "1.0" }, + "panel_visibility": { + "mission": true + }, "properties": [ { "name": "Scene.BepiColomboMPO_MertisTis.Renderable.Enabled", @@ -178,6 +181,6 @@ }, "version": { "major": 1, - "minor": 3 + "minor": 4 } } diff --git a/data/profiles/missions/dawn.profile b/data/profiles/missions/dawn.profile index 8a5f89f46b..ad8e77b7db 100644 --- a/data/profiles/missions/dawn.profile +++ b/data/profiles/missions/dawn.profile @@ -49,18 +49,22 @@ ], "meta": { "author": "OpenSpace Team", - "description": "work in progress profile for the dawn mission", + "description": "A work in progress profile for the Dawn mission.", "license": "MIT License", "name": "Dawn", "url": "https://www.openspaceproject.com", "version": "1.0" }, + "panel_visibility": { + "mission": true + }, "time": { + "is_paused": false, "type": "absolute", "value": "2011-08-06T00:00:00" }, "version": { "major": 1, - "minor": 0 + "minor": 4 } } diff --git a/data/profiles/missions/euclid.profile b/data/profiles/missions/euclid.profile index 8db9bcf69c..2f8597612b 100644 --- a/data/profiles/missions/euclid.profile +++ b/data/profiles/missions/euclid.profile @@ -39,28 +39,16 @@ ], "meta": { "author": "OpenSpace Team", - "description": "A profile showing the trajectory of ESA's Euclid mission", + "description": "A profile showing the trajectory of ESA's Euclid mission.", "license": "MIT License", "name": "Euclid", "url": "https://www.openspaceproject.com", "version": "1.0" }, + "panel_visibility": { + "mission": true + }, "properties": [ - { - "name": "Scene.L2.Renderable.Enabled", - "type": "setPropertyValueSingle", - "value": "false" - }, - { - "name": "Scene.L2Label.Renderable.Enabled", - "type": "setPropertyValueSingle", - "value": "false" - }, - { - "name": "Scene.L2SmallLabel.Renderable.Enabled", - "type": "setPropertyValueSingle", - "value": "false" - }, { "name": "Scene.EuclidTrailSun.Renderable.Enabled", "type": "setPropertyValueSingle", @@ -84,6 +72,6 @@ }, "version": { "major": 1, - "minor": 3 + "minor": 4 } } diff --git a/data/profiles/missions/gaia.profile b/data/profiles/missions/gaia.profile index aebb5413ca..e85b8027aa 100644 --- a/data/profiles/missions/gaia.profile +++ b/data/profiles/missions/gaia.profile @@ -34,7 +34,7 @@ ], "meta": { "author": "OpenSpace Team", - "description": "This scene contains a new rendering method to show the massive ESA Gaia stars dataset. By default, it loads the few million stars of the Gaia DR2 that contain radial velocities", + "description": "This scene contains a new rendering method to show the massive ESA Gaia stars dataset. By default, it loads the few million stars of the Gaia DR2 that contain radial velocities.", "license": "MIT License", "name": "Gaia", "url": "https://www.openspaceproject.com", @@ -47,6 +47,9 @@ "notLoadedInstruction": "openspace.printFatal('Could not load gaia profile due to missing module \"Gaia\"')" } ], + "panel_visibility": { + "mission": true + }, "properties": [ { "name": "Scene.Stars.Renderable.Enabled", @@ -55,11 +58,12 @@ } ], "time": { + "is_paused": false, "type": "absolute", "value": "2019-06-10T00:00:00" }, "version": { "major": 1, - "minor": 0 + "minor": 4 } } diff --git a/data/profiles/missions/juice.profile b/data/profiles/missions/juice.profile index 3fd45ae004..bfb2740056 100644 --- a/data/profiles/missions/juice.profile +++ b/data/profiles/missions/juice.profile @@ -50,12 +50,15 @@ ], "meta": { "author": "OpenSpace Team", - "description": "Juice profile that visualizes the currently best known trajectory for the JUICE mission the Jupiter and its moons. See https://sci.esa.int/documents/33960/35865/1567260128466-JUICE_Red_Book_i1.0.pdf for more information about the JUICE mission. Currently, only the Janus and NavCam instruments are included in this profile, but the other instruments are available for a custom profile. Some of these are not behaving correctly, which will be addressed later", + "description": "Juice profile that visualizes the currently best known trajectory for the JUICE mission the Jupiter and its moons. See https://sci.esa.int/documents/33960/35865/1567260128466-JUICE_Red_Book_i1.0.pdf for more information about the JUICE mission. Currently, only the Janus and NavCam instruments are included in this profile, but the other instruments are available for a custom profile. Some of these are not behaving correctly, which will be addressed later.", "license": "MIT License", "name": "Juice", "url": "https://www.openspaceproject.com", "version": "1.0" }, + "panel_visibility": { + "mission": true + }, "properties": [ { "name": "NavigationHandler.OrbitalNavigator.LimitZoom.MinimumAllowedDistance", @@ -78,7 +81,7 @@ "value": "false" }, { - "name": "Scene.GanymedeMagnetosphere.Renderable.DomainEnabled", + "name": "Scene.GanymedeMagnetosphere.Renderable.Domain.DomainEnabled", "type": "setPropertyValueSingle", "value": "false" }, @@ -103,12 +106,12 @@ "value": "40" }, { - "name": "Scene.GanymedeMagnetosphere.Renderable.Flow.Speed", + "name": "Scene.GanymedeMagnetosphere.Renderable.Flow.FlowSpeed", "type": "setPropertyValueSingle", "value": "150.000000" }, { - "name": "Scene.GanymedeMagnetosphere.Renderable.FlowEnabled", + "name": "Scene.GanymedeMagnetosphere.Renderable.Flow.FlowEnabled", "type": "setPropertyValueSingle", "value": "true" }, @@ -130,6 +133,6 @@ }, "version": { "major": 1, - "minor": 2 + "minor": 4 } } diff --git a/data/profiles/missions/juno.profile b/data/profiles/missions/juno.profile index 99d8c8e30c..3c8f67d74f 100644 --- a/data/profiles/missions/juno.profile +++ b/data/profiles/missions/juno.profile @@ -48,18 +48,22 @@ ], "meta": { "author": "OpenSpace Team", - "description": "work in progress scene for juno", + "description": "A work in progress profile for Juno.", "license": "MIT License", "name": "Juno", "url": "https://www.openspaceproject.com", "version": "0.1" }, + "panel_visibility": { + "mission": true + }, "time": { + "is_paused": false, "type": "absolute", "value": "2016-07-01T10:05:00" }, "version": { "major": 1, - "minor": 0 + "minor": 4 } } diff --git a/data/profiles/missions/jwst.profile b/data/profiles/missions/jwst.profile index 521fa3a859..d35e7b481b 100644 --- a/data/profiles/missions/jwst.profile +++ b/data/profiles/missions/jwst.profile @@ -1,7 +1,4 @@ { - "additional_scripts": [ - "openspace.setPropertyValue(\"Scene.MoonTrail.Renderable.Appearance.Color\", {0.7, 0.5, 0.5});" - ], "assets": [ "base", "base_keybindings", @@ -122,15 +119,18 @@ ], "meta": { "author": "OpenSpace Team", - "description": "James Webb Space Telescope Profile. Adds the James Webb Space Telescope model with an estimated trajectery", + "description": "James Webb Space Telescope Profile. Adds the James Webb Space Telescope model with an estimated trajectory.", "license": "MIT License", "name": "James Webb Space Telescope", "url": "https://www.openspaceproject.com", "version": "1.0" }, + "panel_visibility": { + "mission": true + }, "properties": [ { - "name": "{earth_satellites}.Renderable.Enabled", + "name": "{earth_satellites~space_stations}.Renderable.Enabled", "type": "setPropertyValue", "value": "false" }, @@ -245,9 +245,14 @@ "value": "false" }, { - "name": "Scene.Earth.Renderable.Layers.ColorLayers.VIIRS_NOAA20_Temporal.Enabled", + "name": "Scene.Earth.Renderable.Layers.ColorLayers.Temporal_NOAA20_VIIRS.Enabled", "type": "setPropertyValueSingle", "value": "true" + }, + { + "name": "Scene.MoonTrail.Renderable.Appearance.Color", + "type": "setPropertyValueSingle", + "value": "{0.7, 0.5, 0.5}" } ], "time": { @@ -257,6 +262,6 @@ }, "version": { "major": 1, - "minor": 2 + "minor": 4 } } diff --git a/data/profiles/missions/mars.profile b/data/profiles/missions/mars.profile index 746bc98ddf..3bcdd3f89a 100644 --- a/data/profiles/missions/mars.profile +++ b/data/profiles/missions/mars.profile @@ -54,18 +54,22 @@ ], "meta": { "author": "OpenSpace Team", - "description": "This profile shows the landing of the NASA InSight lander on Mars. The final minutes of the approach are shown with the lander finishing on the surface of Mars. This profile also includes the landing trail and model for the Mars2020 rover Perseverence. ", + "description": "This profile shows the landing of the NASA InSight lander on Mars. The final minutes of the approach are shown with the lander finishing on the surface of Mars. This profile also includes the landing trail and model for the Mars2020 rover Perseverence.", "license": "MIT License", "name": "Mars", "url": "https://www.openspaceproject.com", "version": "1.0" }, + "panel_visibility": { + "mission": true + }, "time": { + "is_paused": false, "type": "relative", "value": "-1d" }, "version": { "major": 1, - "minor": 1 + "minor": 4 } } diff --git a/data/profiles/missions/messenger.profile b/data/profiles/missions/messenger.profile index a8df550841..6f5c5d66a0 100644 --- a/data/profiles/missions/messenger.profile +++ b/data/profiles/missions/messenger.profile @@ -42,18 +42,22 @@ ], "meta": { "author": "OpenSpace Team", - "description": "This scene contains model and trajectory of the NASA MESSENGER spacecraft with craft pointing data from 2011-03 to 2011-06. In addition, a rendering of Mercury's magnetosphere based on data recorded by MESSENGER can be enabled and viewed around the planet. Along with the mission data, additional maps were added to Mercury showing mineral abundances on the surface and a multi-color mosaic from the MDIS instrument", + "description": "This scene contains model and trajectory of the NASA MESSENGER spacecraft with pointing data from 2011-03 to 2011-06. In addition, a rendering of Mercury's magnetosphere based on data recorded by MESSENGER can be enabled and viewed around the planet. Along with the mission data, additional maps were added to Mercury showing mineral abundances on the surface and a multi-color mosaic from the MDIS instrument.", "license": "MIT License", "name": "Messenger", "url": "https://www.openspaceproject.com", "version": "1.0" }, + "panel_visibility": { + "mission": true + }, "time": { + "is_paused": false, "type": "absolute", "value": "2011-05-13T08:55:00" }, "version": { "major": 1, - "minor": 0 + "minor": 4 } } diff --git a/data/profiles/missions/newhorizons.profile b/data/profiles/missions/newhorizons.profile index cf78184d76..a204b8e176 100644 --- a/data/profiles/missions/newhorizons.profile +++ b/data/profiles/missions/newhorizons.profile @@ -125,12 +125,15 @@ ], "meta": { "author": "OpenSpace Team", - "description": "This profile shows the acquisition of NASA New Horizons' images of the Plutonian system in July 2015. The profile starts at around 10:00 on July 14th, around 10 minutes before a new image campaign starts. By selecting Pluto as the Origin and moving time faster, you can see the imprint of the instrument's field-of-view on the planetary surface and see the images being projected. A timer on the top left of the screen shows when the next image is being taken", + "description": "This profile shows the acquisition of NASA New Horizons' images of the Plutonian system in July 2015. The profile starts at around 10:00 on July 14th, around 10 minutes before a new image campaign starts. By selecting Pluto as the Origin and moving time faster, you can see the imprint of the instrument's field-of-view on the planetary surface and see the images being projected. A timer on the top left of the screen shows when the next image is being taken.", "license": "MIT License", "name": "New Horizons", "url": "https://www.openspaceproject.com", "version": "1.1" }, + "panel_visibility": { + "mission": true + }, "properties": [ { "name": "Scene.Pluto.Renderable.Enabled", @@ -184,11 +187,12 @@ } ], "time": { + "is_paused": false, "type": "absolute", "value": "2015-07-14T08:00:00" }, "version": { "major": 1, - "minor": 1 + "minor": 4 } } diff --git a/data/profiles/missions/osirisrex.profile b/data/profiles/missions/osirisrex.profile index 3cd0af20d1..cac5189551 100644 --- a/data/profiles/missions/osirisrex.profile +++ b/data/profiles/missions/osirisrex.profile @@ -77,12 +77,15 @@ ], "meta": { "author": "OpenSpace Team", - "description": "This profile demonstrates the entire lifetime of the NASA OSIRIS-REx spacecraft on its way to the asteroid Bennu and its subsequent journey back to Earth. The profile starts at Earth around the time of the spacecraft's launch and has information throughout the entire mission until its landing back on Earth in Utah. The models of OSIRIS-REx and Bennu are available, as well as a preliminary instrument timing, which uses the same image projection technique as employed in New Horizons and Rosetta", + "description": "This profile demonstrates the entire lifetime of the NASA OSIRIS-REx spacecraft on its way to the asteroid Bennu and its subsequent journey back to Earth. The profile starts at Earth around the time of the spacecraft's launch and has information throughout the entire mission until its landing back on Earth in Utah. The models of OSIRIS-REx and Bennu are available, as well as a preliminary instrument timing, which uses the same image projection technique as employed in New Horizons and Rosetta.", "license": "MIT License", "name": "Osiris-Rex", "url": "https://www.openspaceproject.com", "version": "1.1" }, + "panel_visibility": { + "mission": true + }, "properties": [ { "name": "NavigationHandler.OrbitalNavigator.FollowAnchorNodeRotationDistance", @@ -96,11 +99,12 @@ } ], "time": { + "is_paused": false, "type": "absolute", "value": "2018-10-30T23:00:00" }, "version": { "major": 1, - "minor": 1 + "minor": 4 } } diff --git a/data/profiles/missions/rosetta.profile b/data/profiles/missions/rosetta.profile index a9daac0c90..6d843407a7 100644 --- a/data/profiles/missions/rosetta.profile +++ b/data/profiles/missions/rosetta.profile @@ -90,12 +90,15 @@ ], "meta": { "author": "OpenSpace Team", - "description": "The Rosetta scene shows the entire mission of ESA's Rosetta spacecraft around comet 67P, also known as Churyumov-Gerasimenko. The spacecraft's images are projected onto the comet and the separation of the Philae lander is visible as well", + "description": "The Rosetta scene shows the entire mission of ESA's Rosetta spacecraft around comet 67P, also known as Churyumov-Gerasimenko. The spacecraft's images are projected onto the comet and the separation of the Philae lander is visible as well.", "license": "MIT License", "name": "Rosetta", "url": "https://www.openspaceproject.com", "version": "1.2" }, + "panel_visibility": { + "mission": true + }, "properties": [ { "name": "Scene.67P.Renderable.PerformShading", @@ -115,6 +118,6 @@ }, "version": { "major": 1, - "minor": 2 + "minor": 4 } } diff --git a/data/profiles/missions/voyager.profile b/data/profiles/missions/voyager.profile index 7fdae4dea9..03d4eb7483 100644 --- a/data/profiles/missions/voyager.profile +++ b/data/profiles/missions/voyager.profile @@ -83,12 +83,15 @@ ], "meta": { "author": "OpenSpace Team", - "description": "This scene contains the NASA Voyager 1 and Voyager 2 missions as they were launched from Earth in the 1970s and observed the gas giants in the Solar System. The spacecraft models are included and are pointed accurately throughout the mission. Position and orientation information are available until the second half of the 21st century", + "description": "This scene contains the NASA Voyager 1 and Voyager 2 missions as they were launched from Earth in the 1970s and observed the gas giants in the Solar System. The spacecraft models are included and are pointed accurately throughout the mission. Position and orientation information are available until the second half of the 21st century.", "license": "MIT License", "name": "Voyager", "url": "https://www.openspaceproject.com", "version": "1.1" }, + "panel_visibility": { + "mission": true + }, "properties": [ { "name": "Scene.PlutoBarycenterTrail.Renderable.Enabled", @@ -97,11 +100,12 @@ } ], "time": { + "is_paused": false, "type": "absolute", "value": "1977-09-10T12:00:00" }, "version": { "major": 1, - "minor": 1 + "minor": 4 } } diff --git a/data/profiles/nightsky.profile b/data/profiles/nightsky.profile index f7354ac731..8af08e1a51 100644 --- a/data/profiles/nightsky.profile +++ b/data/profiles/nightsky.profile @@ -1,6 +1,24 @@ { + "actions": [ + { + "documentation": "Sets the stars back to their default values", + "gui_path": "/Night Sky/Stars", + "identifier": "os.nightsky.DefaultStars", + "is_local": false, + "name": "Set default star values", + "script": "openspace.setPropertyValueSingle(\"Scene.Stars.Renderable.Core.Multiplier\", 15.0)\nopenspace.setPropertyValueSingle(\"Scene.Stars.Renderable.Core.Gamma\", 1.66)\nopenspace.setPropertyValueSingle(\"Scene.Stars.Renderable.Core.Scale\", 0.18)\n\nopenspace.setPropertyValueSingle(\"Scene.Stars.Renderable.Glare.Multiplier\", 0.65)\nopenspace.setPropertyValueSingle(\"Scene.Stars.Renderable.Glare.Gamma\", 1.0)\nopenspace.setPropertyValueSingle(\"Scene.Stars.Renderable.Glare.Scale\", 1.0)" + }, + { + "documentation": "Changes the values for Core/Glare on the Stars to be more point-like", + "gui_path": "/Night Sky/Stars", + "identifier": "os.nightsky.PointlikeStars", + "is_local": false, + "name": "Set the star values to be more point-like", + "script": "openspace.setPropertyValueSingle(\"Scene.Stars.Renderable.Core.Multiplier\", 2.62)\nopenspace.setPropertyValueSingle(\"Scene.Stars.Renderable.Core.Gamma\", 1.6)\nopenspace.setPropertyValueSingle(\"Scene.Stars.Renderable.Core.Scale\", 1.0)\nopenspace.setPropertyValueSingle(\"Scene.Stars.Renderable.Glare.Multiplier\", 1.75)\nopenspace.setPropertyValueSingle(\"Scene.Stars.Renderable.Glare.Gamma\", 1.19)\nopenspace.setPropertyValueSingle(\"Scene.Stars.Renderable.Glare.Scale\", 0.16)" + } + ], "additional_scripts": [ - "openspace.action.triggerAction(\"os.nightsky.LevelHorizonPitch\")" + "openspace.action.triggerAction(\"os.nightsky.ShowNightSkyPlanets\")" ], "assets": [ "base", @@ -10,7 +28,7 @@ "scene/solarsystem/planets/earth/satellites/satellites" ], "camera": { - "altitude": 50.0, + "altitude": 500.0, "anchor": "Earth", "latitude": 58.5877, "longitude": 16.1652, @@ -43,13 +61,16 @@ "author": "OpenSpace Team", "description": "A profile starting at night on the surface of earth looking out at the horizon. The city lights map has been disabled.", "license": "MIT License", - "name": "Default", + "name": "Nights Sky", "url": "https://www.openspaceproject.com", "version": "1.0" }, + "panel_visibility": { + "nightSky": true + }, "properties": [ { - "name": "{earth_satellites}.Renderable.Enabled", + "name": "{earth_satellites~space_stations}.Renderable.Enabled", "type": "setPropertyValue", "value": "false" }, @@ -66,6 +87,6 @@ }, "version": { "major": 1, - "minor": 2 + "minor": 4 } } diff --git a/data/profiles/spaceweather/bastilleday2000.profile b/data/profiles/spaceweather/bastilleday2000.profile index ae6fe37d51..4b2c04a6be 100644 --- a/data/profiles/spaceweather/bastilleday2000.profile +++ b/data/profiles/spaceweather/bastilleday2000.profile @@ -13,7 +13,6 @@ "scene/solarsystem/heliosphere/bastille_day/magnetogram", "scene/solarsystem/heliosphere/bastille_day/magnetogram_textures", "scene/solarsystem/planets/earth/magnetosphere/magnetosphere", - "scene/solarsystem/planets/earth/magnetosphere/transforms_magnetosphere", "scene/solarsystem/planets/earth/satellites/satellites", "scene/solarsystem/sun/euv_layer" ], @@ -80,7 +79,7 @@ "key": "I" }, { - "action": "os.solarsystem.ToggleEuv", + "action": "os.solarsystem.sun.ToggleEuv", "key": "E" }, { @@ -110,15 +109,15 @@ ], "meta": { "author": "CCMC", - "description": "This profile is showing the Coronal mass ejection of the bastille day 2000-07-14. The profile is data intensive and will require a powerful GPU", + "description": "This profile is showing the Coronal mass ejection of the bastille day 2000-07-14. The profile is data intensive and will require a powerful GPU.", "license": "MIT License", - "name": "Bastille day 2000", + "name": "Bastille Day 2000", "url": "https://www.openspaceproject.com", "version": "1.1" }, "properties": [ { - "name": "{earth_satellites}.Renderable.Enabled", + "name": "{earth_satellites~space_stations}.Renderable.Enabled", "type": "setPropertyValue", "value": "false" }, @@ -154,11 +153,12 @@ } ], "time": { + "is_paused": false, "type": "absolute", "value": "2000-07-14T08:42:00" }, "version": { "major": 1, - "minor": 1 + "minor": 4 } } diff --git a/data/profiles/spaceweather/solarstorm2012.profile b/data/profiles/spaceweather/solarstorm2012.profile index 1a967879de..baa1452e7a 100644 --- a/data/profiles/spaceweather/solarstorm2012.profile +++ b/data/profiles/spaceweather/solarstorm2012.profile @@ -63,9 +63,9 @@ ], "meta": { "author": "Community Coordinated Modeling Center, NASA Goddard", - "description": "This profile is showing several coronal mass ejection (CMEs) during July 2012, where the last one was incredible intense. Its strength was comparable to the most intense CME in recorded history, the Carrington Event of 1859, which caused damage to electric equipment world wide. Luckily this 2012 event missed earth. The event is modeled with ENLIL which spands across the solarsystem, from the Sun to Earth, Batsrus which is showing the interaction of the flow of the solar wind and Earths magnetosphere. There is also one time step of the PFSS model showing the Suns local magnetic structure", + "description": "This profile is showing several coronal mass ejection (CMEs) during July 2012, where the last one was incredible intense. Its strength was comparable to the most intense CME in recorded history, the Carrington Event of 1859, which caused damage to electric equipment world wide. Luckily this 2012 event missed earth. The event is modeled with ENLIL which spands across the solarsystem, from the Sun to Earth, Batsrus which is showing the interaction of the flow of the solar wind and Earths magnetosphere. There is also one time step of the PFSS model showing the Suns local magnetic structure.", "license": "MIT License", - "name": "Solar storm 2012", + "name": "Solar Storm 2012", "url": "https://www.openspaceproject.com", "version": "1.0" }, @@ -87,11 +87,12 @@ } ], "time": { + "is_paused": false, "type": "absolute", "value": "2012-07-14T07:00:00" }, "version": { "major": 1, - "minor": 1 + "minor": 4 } } diff --git a/data/profiles/spaceweather/todays_sun.profile b/data/profiles/spaceweather/todays_sun.profile new file mode 100644 index 0000000000..2a1f03812a --- /dev/null +++ b/data/profiles/spaceweather/todays_sun.profile @@ -0,0 +1,164 @@ +{ + "assets": [ + "base", + "base_keybindings", + "scene/solarsystem/heliosphere/todayssun/fieldlines", + "scene/solarsystem/heliosphere/todayssun/grid", + "scene/solarsystem/heliosphere/todayssun/mission", + "scene/solarsystem/heliosphere/todayssun/sun_earth_line", + "scene/solarsystem/heliosphere/todayssun/surfaces", + "scene/solarsystem/planets/earth/earth", + "scene/solarsystem/planets/earth/satellites/satellites" + ], + "camera": { + "altitude": 4578000000.0, + "anchor": "Sun", + "latitude": 1.5877, + "longitude": -150.1924, + "type": "goToGeo" + }, + "delta_times": [ + 1.0, + 5.0, + 30.0, + 60.0, + 300.0, + 1800.0, + 3600.0, + 43200.0, + 86400.0, + 604800.0, + 1209600.0, + 2592000.0, + 5184000.0, + 7776000.0, + 15552000.0, + 31536000.0, + 63072000.0, + 157680000.0, + 315360000.0, + 630720000.0 + ], + "keybindings": [ + { + "action": "os.solarsystem.ToggleSatelliteTrails", + "key": "S" + } + ], + "mark_nodes": [ + "Sun", + "Earth" + ], + "meta": { + "author": "OpenSpace Team", + "description": "This profile uses simulation outputs in real time from the model WSA to visualize the magnetic fluctuations on the Sun.", + "license": "MIT License", + "name": "Todays Sun", + "url": "https://www.openspaceproject.com", + "version": "1.0" + }, + "panel_visibility": { + "exoplanets": false, + "flightControl": false, + "geoLocation": false, + "gettingStartedTour": false, + "mission": true, + "skyBrowser": false + }, + "properties": [ + { + "name": "{earth_satellites}.Renderable.Enabled", + "type": "setPropertyValue", + "value": "false" + }, + { + "name": "Scene.Sun.Renderable.Enabled", + "type": "setPropertyValueSingle", + "value": "true" + }, + { + "name": "Scene.SunGlare.Renderable.Enabled", + "type": "setPropertyValueSingle", + "value": "false" + }, + { + "name": "Scene.Earth.Renderable.Layers.ColorLayers.Blue_Marble.Enabled", + "type": "setPropertyValueSingle", + "value": "true" + }, + { + "name": "Scene.Earth.Renderable.Layers.ColorLayers.ESRI_VIIRS_Combo.Enabled", + "type": "setPropertyValueSingle", + "value": "false" + }, + { + "name": "Scene.WSA_54_velocity_GONGZ_Outer_Boundary.Renderable.Enabled", + "type": "setPropertyValueSingle", + "value": "false" + }, + { + "name": "Scene.WSA_54_velocity_ADAPT_Outer_Boundary.Renderable.Enabled", + "type": "setPropertyValueSingle", + "value": "false" + }, + { + "name": "Scene.WSA_54_Magnetograms_ADAPT.Renderable.Enabled", + "type": "setPropertyValueSingle", + "value": "false" + }, + { + "name": "Scene.WSA_54_Magnetograms_GONGZ.Renderable.Enabled", + "type": "setPropertyValueSingle", + "value": "true" + }, + { + "name": "Scene.WSA_54_Magnetic_Field_ADAPT_5_Rs.Renderable.Enabled", + "type": "setPropertyValueSingle", + "value": "false" + }, + { + "name": "Scene.WSA_54_Magnetic_Field_GONGZ_5_Rs.Renderable.Enabled", + "type": "setPropertyValueSingle", + "value": "false" + }, + { + "name": "Scene.WSA_54_Fieldlines_PFSS_IO.Renderable.Enabled", + "type": "setPropertyValueSingle", + "value": "true" + }, + { + "name": "Scene.WSA_54_Fieldlines_PFSS_OI.Renderable.Enabled", + "type": "setPropertyValueSingle", + "value": "true" + }, + { + "name": "Scene.WSA_54_Fieldlines_SCS_OI.Renderable.Enabled", + "type": "setPropertyValueSingle", + "value": "false" + }, + { + "name": "Scene.WSA_54_Fieldlines_Earth.Renderable.Enabled", + "type": "setPropertyValueSingle", + "value": "false" + }, + { + "name": "Scene.WSA_54_Fieldlines_PFSS_IO.Renderable.ABlendingEnabled", + "type": "setPropertyValueSingle", + "value": "false" + }, + { + "name": "Scene.WSA_54_Fieldlines_PFSS_IO.Renderable.LineWidth", + "type": "setPropertyValueSingle", + "value": "2.0" + } + ], + "time": { + "is_paused": false, + "type": "relative", + "value": "-2h" + }, + "version": { + "major": 1, + "minor": 4 + } +} diff --git a/data/profiles/touch.profile b/data/profiles/touch.profile deleted file mode 100644 index c7a3813303..0000000000 --- a/data/profiles/touch.profile +++ /dev/null @@ -1,56 +0,0 @@ -{ - "additional_scripts": [ - "openspace.setPropertyValueSingle(\"Modules.CefWebGui.GuiUrl\", 'http://127.0.0.1:4680/frontend/#/ontouch');" - ], - "assets": [ - "base", - "base_keybindings" - ], - "camera": { - "altitude": 20000000.0, - "anchor": "Earth", - "latitude": 58.5877, - "longitude": 16.1924, - "type": "goToGeo" - }, - "meta": { - "author": "OpenSpace Team", - "description": "Profile set up to load /touch path from the gui, which contains an alternate gui with stories for a touch screen", - "license": "MIT License", - "name": "Touch", - "url": "https://www.openspaceproject.com", - "version": "1.0" - }, - "modules": [ - { - "loadedInstruction": "", - "name": "Touch", - "notLoadedInstruction": "openspace.printFatal('Could not load scene due to missing module \"touch\"');" - } - ], - "properties": [ - { - "name": "Scene.PlutoBarycenterTrail.Renderable.Enabled", - "type": "setPropertyValue", - "value": "false" - }, - { - "name": "Scene.Pluto.Renderable.Enabled", - "type": "setPropertyValue", - "value": "false" - }, - { - "name": "Scene.Charon.Renderable.Enabled", - "type": "setPropertyValue", - "value": "false" - } - ], - "time": { - "type": "relative", - "value": "-1d" - }, - "version": { - "major": 1, - "minor": 0 - } -} diff --git a/data/tasks/convertmodel.task b/data/tasks/convertmodel.task new file mode 100644 index 0000000000..fdd078c6fd --- /dev/null +++ b/data/tasks/convertmodel.task @@ -0,0 +1,7 @@ +return { + { + Type = "ConvertModelTask", + InputFilePath = "< in path >", + OutputFilePath = "< out path >" + } +} diff --git a/data/test4.jpg b/data/test4.jpg new file mode 100644 index 0000000000..e6b1b7eeca Binary files /dev/null and b/data/test4.jpg differ diff --git a/data/test5.jpg b/data/test5.jpg new file mode 100644 index 0000000000..ef95897885 Binary files /dev/null and b/data/test5.jpg differ diff --git a/data/web/default_ui_panels.json b/data/web/default_ui_panels.json new file mode 100644 index 0000000000..e964e1f23d --- /dev/null +++ b/data/web/default_ui_panels.json @@ -0,0 +1,110 @@ +{ + "0": { + "id": "scene", + "visible": true, + "name": "Scene", + "isOpen": false + }, + "1": { + "id": "settings", + "visible": false, + "name": "Settings", + "isOpen": false + }, + "2": { + "id": "navigation", + "visible": true, + "name": "Navigation", + "isOpen": false + }, + "3": { + "id": "timePanel", + "visible": true, + "name": "Time Panel", + "isOpen": false + }, + "4": { + "id": "sessionRecording", + "visible": true, + "name": "Session Recording", + "isOpen": false + }, + "5": { + "id": "geoLocation", + "visible": true, + "name": "Geo Location", + "isOpen": false + }, + "6": { + "id": "screenSpaceRenderables", + "visible": true, + "name": "Screenspace Renderables", + "isOpen": false + }, + "7": { + "id": "exoplanets", + "visible": true, + "name": "Exoplanets", + "isOpen": false + }, + "8": { + "id": "userPanels", + "visible": true, + "name": "User Panels", + "isOpen": false + }, + "9": { + "id": "actions", + "visible": true, + "name": "Actions", + "isOpen": false + }, + "10": { + "id": "skyBrowser", + "visible": true, + "name": "SkyBrowser", + "isOpen": false + }, + "11": { + "id": "mission", + "visible": false, + "name": "Mission", + "isOpen": false + }, + "12": { + "id": "flightControl", + "visible": true, + "name": "Flight Control", + "isOpen": false + }, + "13": { + "id": "keybindingsLayout", + "visible": false, + "name": "Keybinds", + "isOpen": false + }, + "14": { + "id": "nightSky", + "visible": false, + "name": "Night Sky", + "isOpen": false + }, + "15": { + "id": "gettingStartedTour", + "visible": false, + "name": "Getting Started Tour", + "isOpen": false + }, + "16": { + "id": "scriptLogPanel", + "visible": false, + "name": "Script Log", + "isOpen": false + }, + "17": { + "id": "devPanel", + "visible": false, + "name": "Dev Panel", + "isOpen": false + } +} \ No newline at end of file diff --git a/ext/CMakeLists.txt b/ext/CMakeLists.txt index 2a42f99780..1bc3a5fb16 100644 --- a/ext/CMakeLists.txt +++ b/ext/CMakeLists.txt @@ -62,6 +62,11 @@ target_compile_features(spice PUBLIC cxx_std_20) set_target_properties(spice PROPERTIES FOLDER "External") end_dependency() +# nlohmann +begin_dependency("nlohmann") +add_subdirectory(json) +end_dependency() + # Curl begin_dependency("CURL") if (WIN32) diff --git a/ext/date b/ext/date index 569b2d6785..5bdb7e6f31 160000 --- a/ext/date +++ b/ext/date @@ -1 +1 @@ -Subproject commit 569b2d678547985d0ead3b73ee93a28919000887 +Subproject commit 5bdb7e6f31fac909c090a46dbd9fea27b6e609a4 diff --git a/ext/ghoul b/ext/ghoul index e7ff4891f4..9660f8eee1 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit e7ff4891f43e1358e03f344faba81e137334b6dc +Subproject commit 9660f8eee19b9ef4ec689ae73db7fa9da222260e diff --git a/ext/json b/ext/json new file mode 160000 index 0000000000..96c1b52f1c --- /dev/null +++ b/ext/json @@ -0,0 +1 @@ +Subproject commit 96c1b52f1cc4742a00ee02b34e043f61bbffa6ae diff --git a/ext/json/json.hpp b/ext/json/json.hpp deleted file mode 100644 index a70aaf8cbc..0000000000 --- a/ext/json/json.hpp +++ /dev/null @@ -1,25447 +0,0 @@ -/* - __ _____ _____ _____ - __| | __| | | | JSON for Modern C++ -| | |__ | | | | | | version 3.9.1 -|_____|_____|_____|_|___| https://github.com/nlohmann/json - -Licensed under the MIT License . -SPDX-License-Identifier: MIT -Copyright (c) 2013-2019 Niels Lohmann . - -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 INCLUDE_NLOHMANN_JSON_HPP_ -#define INCLUDE_NLOHMANN_JSON_HPP_ - -#define NLOHMANN_JSON_VERSION_MAJOR 3 -#define NLOHMANN_JSON_VERSION_MINOR 9 -#define NLOHMANN_JSON_VERSION_PATCH 1 - -#include // all_of, find, for_each -#include // nullptr_t, ptrdiff_t, size_t -#include // hash, less -#include // initializer_list -#include // istream, ostream -#include // random_access_iterator_tag -#include // unique_ptr -#include // accumulate -#include // string, stoi, to_string -#include // declval, forward, move, pair, swap -#include // vector - -// #include - - -#include - -// #include - - -#include // transform -#include // array -#include // forward_list -#include // inserter, front_inserter, end -#include // map -#include // string -#include // tuple, make_tuple -#include // is_arithmetic, is_same, is_enum, underlying_type, is_convertible -#include // unordered_map -#include // pair, declval -#include // valarray - -// #include - - -#include // exception -#include // runtime_error -#include // to_string - -// #include - - -#include // size_t - -namespace nlohmann -{ -namespace detail -{ -/// struct to capture the start position of the current token -struct position_t -{ - /// the total number of characters read - std::size_t chars_read_total = 0; - /// the number of characters read in the current line - std::size_t chars_read_current_line = 0; - /// the number of lines read - std::size_t lines_read = 0; - - /// conversion to size_t to preserve SAX interface - constexpr operator size_t() const - { - return chars_read_total; - } -}; - -} // namespace detail -} // namespace nlohmann - -// #include - - -#include // pair -// #include -/* Hedley - https://nemequ.github.io/hedley - * Created by Evan Nemerson - * - * To the extent possible under law, the author(s) have dedicated all - * copyright and related and neighboring rights to this software to - * the public domain worldwide. This software is distributed without - * any warranty. - * - * For details, see . - * SPDX-License-Identifier: CC0-1.0 - */ - -#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 13) -#if defined(JSON_HEDLEY_VERSION) - #undef JSON_HEDLEY_VERSION -#endif -#define JSON_HEDLEY_VERSION 13 - -#if defined(JSON_HEDLEY_STRINGIFY_EX) - #undef JSON_HEDLEY_STRINGIFY_EX -#endif -#define JSON_HEDLEY_STRINGIFY_EX(x) #x - -#if defined(JSON_HEDLEY_STRINGIFY) - #undef JSON_HEDLEY_STRINGIFY -#endif -#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x) - -#if defined(JSON_HEDLEY_CONCAT_EX) - #undef JSON_HEDLEY_CONCAT_EX -#endif -#define JSON_HEDLEY_CONCAT_EX(a,b) a##b - -#if defined(JSON_HEDLEY_CONCAT) - #undef JSON_HEDLEY_CONCAT -#endif -#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b) - -#if defined(JSON_HEDLEY_CONCAT3_EX) - #undef JSON_HEDLEY_CONCAT3_EX -#endif -#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c - -#if defined(JSON_HEDLEY_CONCAT3) - #undef JSON_HEDLEY_CONCAT3 -#endif -#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c) - -#if defined(JSON_HEDLEY_VERSION_ENCODE) - #undef JSON_HEDLEY_VERSION_ENCODE -#endif -#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision)) - -#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR) - #undef JSON_HEDLEY_VERSION_DECODE_MAJOR -#endif -#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000) - -#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR) - #undef JSON_HEDLEY_VERSION_DECODE_MINOR -#endif -#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000) - -#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION) - #undef JSON_HEDLEY_VERSION_DECODE_REVISION -#endif -#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000) - -#if defined(JSON_HEDLEY_GNUC_VERSION) - #undef JSON_HEDLEY_GNUC_VERSION -#endif -#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__) - #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) -#elif defined(__GNUC__) - #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0) -#endif - -#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK) - #undef JSON_HEDLEY_GNUC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_GNUC_VERSION) - #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_MSVC_VERSION) - #undef JSON_HEDLEY_MSVC_VERSION -#endif -#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) - #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100) -#elif defined(_MSC_FULL_VER) - #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10) -#elif defined(_MSC_VER) - #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0) -#endif - -#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK) - #undef JSON_HEDLEY_MSVC_VERSION_CHECK -#endif -#if !defined(_MSC_VER) - #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0) -#elif defined(_MSC_VER) && (_MSC_VER >= 1400) - #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch))) -#elif defined(_MSC_VER) && (_MSC_VER >= 1200) - #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch))) -#else - #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor))) -#endif - -#if defined(JSON_HEDLEY_INTEL_VERSION) - #undef JSON_HEDLEY_INTEL_VERSION -#endif -#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) - #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE) -#elif defined(__INTEL_COMPILER) - #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0) -#endif - -#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK) - #undef JSON_HEDLEY_INTEL_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_INTEL_VERSION) - #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_PGI_VERSION) - #undef JSON_HEDLEY_PGI_VERSION -#endif -#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__) - #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__) -#endif - -#if defined(JSON_HEDLEY_PGI_VERSION_CHECK) - #undef JSON_HEDLEY_PGI_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_PGI_VERSION) - #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_SUNPRO_VERSION) - #undef JSON_HEDLEY_SUNPRO_VERSION -#endif -#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000) - #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10) -#elif defined(__SUNPRO_C) - #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf) -#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000) - #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10) -#elif defined(__SUNPRO_CC) - #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf) -#endif - -#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK) - #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_SUNPRO_VERSION) - #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION) - #undef JSON_HEDLEY_EMSCRIPTEN_VERSION -#endif -#if defined(__EMSCRIPTEN__) - #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__) -#endif - -#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK) - #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION) - #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_ARM_VERSION) - #undef JSON_HEDLEY_ARM_VERSION -#endif -#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION) - #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100) -#elif defined(__CC_ARM) && defined(__ARMCC_VERSION) - #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100) -#endif - -#if defined(JSON_HEDLEY_ARM_VERSION_CHECK) - #undef JSON_HEDLEY_ARM_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_ARM_VERSION) - #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_IBM_VERSION) - #undef JSON_HEDLEY_IBM_VERSION -#endif -#if defined(__ibmxl__) - #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__) -#elif defined(__xlC__) && defined(__xlC_ver__) - #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff) -#elif defined(__xlC__) - #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0) -#endif - -#if defined(JSON_HEDLEY_IBM_VERSION_CHECK) - #undef JSON_HEDLEY_IBM_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_IBM_VERSION) - #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_VERSION) - #undef JSON_HEDLEY_TI_VERSION -#endif -#if \ - defined(__TI_COMPILER_VERSION__) && \ - ( \ - defined(__TMS470__) || defined(__TI_ARM__) || \ - defined(__MSP430__) || \ - defined(__TMS320C2000__) \ - ) -#if (__TI_COMPILER_VERSION__ >= 16000000) - #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif -#endif - -#if defined(JSON_HEDLEY_TI_VERSION_CHECK) - #undef JSON_HEDLEY_TI_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_VERSION) - #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL2000_VERSION) - #undef JSON_HEDLEY_TI_CL2000_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__) - #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL2000_VERSION) - #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL430_VERSION) - #undef JSON_HEDLEY_TI_CL430_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__) - #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL430_VERSION) - #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_ARMCL_VERSION) - #undef JSON_HEDLEY_TI_ARMCL_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__)) - #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK) - #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_ARMCL_VERSION) - #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL6X_VERSION) - #undef JSON_HEDLEY_TI_CL6X_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__) - #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL6X_VERSION) - #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL7X_VERSION) - #undef JSON_HEDLEY_TI_CL7X_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__) - #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL7X_VERSION) - #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CLPRU_VERSION) - #undef JSON_HEDLEY_TI_CLPRU_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__) - #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CLPRU_VERSION) - #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_CRAY_VERSION) - #undef JSON_HEDLEY_CRAY_VERSION -#endif -#if defined(_CRAYC) - #if defined(_RELEASE_PATCHLEVEL) - #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL) - #else - #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0) - #endif -#endif - -#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK) - #undef JSON_HEDLEY_CRAY_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_CRAY_VERSION) - #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_IAR_VERSION) - #undef JSON_HEDLEY_IAR_VERSION -#endif -#if defined(__IAR_SYSTEMS_ICC__) - #if __VER__ > 1000 - #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000)) - #else - #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(VER / 100, __VER__ % 100, 0) - #endif -#endif - -#if defined(JSON_HEDLEY_IAR_VERSION_CHECK) - #undef JSON_HEDLEY_IAR_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_IAR_VERSION) - #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TINYC_VERSION) - #undef JSON_HEDLEY_TINYC_VERSION -#endif -#if defined(__TINYC__) - #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100) -#endif - -#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK) - #undef JSON_HEDLEY_TINYC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TINYC_VERSION) - #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_DMC_VERSION) - #undef JSON_HEDLEY_DMC_VERSION -#endif -#if defined(__DMC__) - #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf) -#endif - -#if defined(JSON_HEDLEY_DMC_VERSION_CHECK) - #undef JSON_HEDLEY_DMC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_DMC_VERSION) - #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_COMPCERT_VERSION) - #undef JSON_HEDLEY_COMPCERT_VERSION -#endif -#if defined(__COMPCERT_VERSION__) - #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100) -#endif - -#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK) - #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_COMPCERT_VERSION) - #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_PELLES_VERSION) - #undef JSON_HEDLEY_PELLES_VERSION -#endif -#if defined(__POCC__) - #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0) -#endif - -#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK) - #undef JSON_HEDLEY_PELLES_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_PELLES_VERSION) - #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_GCC_VERSION) - #undef JSON_HEDLEY_GCC_VERSION -#endif -#if \ - defined(JSON_HEDLEY_GNUC_VERSION) && \ - !defined(__clang__) && \ - !defined(JSON_HEDLEY_INTEL_VERSION) && \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_ARM_VERSION) && \ - !defined(JSON_HEDLEY_TI_VERSION) && \ - !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL430_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \ - !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \ - !defined(__COMPCERT__) - #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION -#endif - -#if defined(JSON_HEDLEY_GCC_VERSION_CHECK) - #undef JSON_HEDLEY_GCC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_GCC_VERSION) - #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_HAS_ATTRIBUTE) - #undef JSON_HEDLEY_HAS_ATTRIBUTE -#endif -#if defined(__has_attribute) - #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute) -#else - #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE) - #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE -#endif -#if defined(__has_attribute) - #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute) -#else - #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE) - #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE -#endif -#if defined(__has_attribute) - #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute) -#else - #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE) - #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE -#endif -#if \ - defined(__has_cpp_attribute) && \ - defined(__cplusplus) && \ - (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute) -#else - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0) -#endif - -#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS) - #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS -#endif -#if !defined(__cplusplus) || !defined(__has_cpp_attribute) - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) -#elif \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_IAR_VERSION) && \ - (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \ - (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0)) - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute) -#else - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE) - #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE -#endif -#if defined(__has_cpp_attribute) && defined(__cplusplus) - #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) -#else - #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE) - #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE -#endif -#if defined(__has_cpp_attribute) && defined(__cplusplus) - #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) -#else - #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_BUILTIN) - #undef JSON_HEDLEY_HAS_BUILTIN -#endif -#if defined(__has_builtin) - #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin) -#else - #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN) - #undef JSON_HEDLEY_GNUC_HAS_BUILTIN -#endif -#if defined(__has_builtin) - #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) -#else - #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN) - #undef JSON_HEDLEY_GCC_HAS_BUILTIN -#endif -#if defined(__has_builtin) - #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) -#else - #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_FEATURE) - #undef JSON_HEDLEY_HAS_FEATURE -#endif -#if defined(__has_feature) - #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature) -#else - #define JSON_HEDLEY_HAS_FEATURE(feature) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE) - #undef JSON_HEDLEY_GNUC_HAS_FEATURE -#endif -#if defined(__has_feature) - #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) -#else - #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_FEATURE) - #undef JSON_HEDLEY_GCC_HAS_FEATURE -#endif -#if defined(__has_feature) - #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) -#else - #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_EXTENSION) - #undef JSON_HEDLEY_HAS_EXTENSION -#endif -#if defined(__has_extension) - #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension) -#else - #define JSON_HEDLEY_HAS_EXTENSION(extension) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION) - #undef JSON_HEDLEY_GNUC_HAS_EXTENSION -#endif -#if defined(__has_extension) - #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) -#else - #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION) - #undef JSON_HEDLEY_GCC_HAS_EXTENSION -#endif -#if defined(__has_extension) - #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) -#else - #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE) - #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE -#endif -#if defined(__has_declspec_attribute) - #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute) -#else - #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE) - #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE -#endif -#if defined(__has_declspec_attribute) - #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) -#else - #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE) - #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE -#endif -#if defined(__has_declspec_attribute) - #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) -#else - #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_WARNING) - #undef JSON_HEDLEY_HAS_WARNING -#endif -#if defined(__has_warning) - #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning) -#else - #define JSON_HEDLEY_HAS_WARNING(warning) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_WARNING) - #undef JSON_HEDLEY_GNUC_HAS_WARNING -#endif -#if defined(__has_warning) - #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) -#else - #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_WARNING) - #undef JSON_HEDLEY_GCC_HAS_WARNING -#endif -#if defined(__has_warning) - #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) -#else - #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for - HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ -#endif -#if defined(__cplusplus) -# if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat") -# if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions") -# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ - _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \ - xpr \ - JSON_HEDLEY_DIAGNOSTIC_POP -# else -# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ - xpr \ - JSON_HEDLEY_DIAGNOSTIC_POP -# endif -# endif -#endif -#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x -#endif - -#if defined(JSON_HEDLEY_CONST_CAST) - #undef JSON_HEDLEY_CONST_CAST -#endif -#if defined(__cplusplus) -# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast(expr)) -#elif \ - JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \ - ((T) (expr)); \ - JSON_HEDLEY_DIAGNOSTIC_POP \ - })) -#else -# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr)) -#endif - -#if defined(JSON_HEDLEY_REINTERPRET_CAST) - #undef JSON_HEDLEY_REINTERPRET_CAST -#endif -#if defined(__cplusplus) - #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast(expr)) -#else - #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr)) -#endif - -#if defined(JSON_HEDLEY_STATIC_CAST) - #undef JSON_HEDLEY_STATIC_CAST -#endif -#if defined(__cplusplus) - #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast(expr)) -#else - #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr)) -#endif - -#if defined(JSON_HEDLEY_CPP_CAST) - #undef JSON_HEDLEY_CPP_CAST -#endif -#if defined(__cplusplus) -# if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast") -# define JSON_HEDLEY_CPP_CAST(T, expr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \ - ((T) (expr)) \ - JSON_HEDLEY_DIAGNOSTIC_POP -# elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0) -# define JSON_HEDLEY_CPP_CAST(T, expr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("diag_suppress=Pe137") \ - JSON_HEDLEY_DIAGNOSTIC_POP \ -# else -# define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr)) -# endif -#else -# define JSON_HEDLEY_CPP_CAST(T, expr) (expr) -#endif - -#if \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ - defined(__clang__) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \ - (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR)) - #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value) -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) - #define JSON_HEDLEY_PRAGMA(value) __pragma(value) -#else - #define JSON_HEDLEY_PRAGMA(value) -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH) - #undef JSON_HEDLEY_DIAGNOSTIC_PUSH -#endif -#if defined(JSON_HEDLEY_DIAGNOSTIC_POP) - #undef JSON_HEDLEY_DIAGNOSTIC_POP -#endif -#if defined(__clang__) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop") -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push)) - #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop)) -#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop") -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop") -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") -#else - #define JSON_HEDLEY_DIAGNOSTIC_PUSH - #define JSON_HEDLEY_DIAGNOSTIC_POP -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)") -#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996)) -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718") -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)") -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215") -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)") -#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"") -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068)) -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") -#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)") -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030)) -#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097") -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)") -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL -#endif - -#if defined(JSON_HEDLEY_DEPRECATED) - #undef JSON_HEDLEY_DEPRECATED -#endif -#if defined(JSON_HEDLEY_DEPRECATED_FOR) - #undef JSON_HEDLEY_DEPRECATED_FOR -#endif -#if JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) - #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since)) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement)) -#elif defined(__cplusplus) && (__cplusplus >= 201402L) - #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]]) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]]) -#elif \ - JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) - #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since))) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement))) -#elif \ - JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) - #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__)) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__)) -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) - #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated) -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated") - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated") -#else - #define JSON_HEDLEY_DEPRECATED(since) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) -#endif - -#if defined(JSON_HEDLEY_UNAVAILABLE) - #undef JSON_HEDLEY_UNAVAILABLE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since))) -#else - #define JSON_HEDLEY_UNAVAILABLE(available_since) -#endif - -#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT) - #undef JSON_HEDLEY_WARN_UNUSED_RESULT -#endif -#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG) - #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG -#endif -#if (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L) - #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]]) -#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) - #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) -#elif \ - JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) - #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__)) -#elif defined(_Check_return_) /* SAL */ - #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_ - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_ -#else - #define JSON_HEDLEY_WARN_UNUSED_RESULT - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) -#endif - -#if defined(JSON_HEDLEY_SENTINEL) - #undef JSON_HEDLEY_SENTINEL -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) - #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position))) -#else - #define JSON_HEDLEY_SENTINEL(position) -#endif - -#if defined(JSON_HEDLEY_NO_RETURN) - #undef JSON_HEDLEY_NO_RETURN -#endif -#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_NO_RETURN __noreturn -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) -#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L - #define JSON_HEDLEY_NO_RETURN _Noreturn -#elif defined(__cplusplus) && (__cplusplus >= 201103L) - #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]]) -#elif \ - JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) - #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) - #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return") -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) - #define JSON_HEDLEY_NO_RETURN __declspec(noreturn) -#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus) - #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;") -#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) - #define JSON_HEDLEY_NO_RETURN __attribute((noreturn)) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0) - #define JSON_HEDLEY_NO_RETURN __declspec(noreturn) -#else - #define JSON_HEDLEY_NO_RETURN -#endif - -#if defined(JSON_HEDLEY_NO_ESCAPE) - #undef JSON_HEDLEY_NO_ESCAPE -#endif -#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape) - #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__)) -#else - #define JSON_HEDLEY_NO_ESCAPE -#endif - -#if defined(JSON_HEDLEY_UNREACHABLE) - #undef JSON_HEDLEY_UNREACHABLE -#endif -#if defined(JSON_HEDLEY_UNREACHABLE_RETURN) - #undef JSON_HEDLEY_UNREACHABLE_RETURN -#endif -#if defined(JSON_HEDLEY_ASSUME) - #undef JSON_HEDLEY_ASSUME -#endif -#if \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_ASSUME(expr) __assume(expr) -#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume) - #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr) -#elif \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) - #if defined(__cplusplus) - #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr) - #else - #define JSON_HEDLEY_ASSUME(expr) _nassert(expr) - #endif -#endif -#if \ - (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) - #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable() -#elif defined(JSON_HEDLEY_ASSUME) - #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0) -#endif -#if !defined(JSON_HEDLEY_ASSUME) - #if defined(JSON_HEDLEY_UNREACHABLE) - #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1))) - #else - #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr) - #endif -#endif -#if defined(JSON_HEDLEY_UNREACHABLE) - #if \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) - #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value)) - #else - #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE() - #endif -#else - #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value) -#endif -#if !defined(JSON_HEDLEY_UNREACHABLE) - #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0) -#endif - -JSON_HEDLEY_DIAGNOSTIC_PUSH -#if JSON_HEDLEY_HAS_WARNING("-Wpedantic") - #pragma clang diagnostic ignored "-Wpedantic" -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus) - #pragma clang diagnostic ignored "-Wc++98-compat-pedantic" -#endif -#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0) - #if defined(__clang__) - #pragma clang diagnostic ignored "-Wvariadic-macros" - #elif defined(JSON_HEDLEY_GCC_VERSION) - #pragma GCC diagnostic ignored "-Wvariadic-macros" - #endif -#endif -#if defined(JSON_HEDLEY_NON_NULL) - #undef JSON_HEDLEY_NON_NULL -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) - #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__))) -#else - #define JSON_HEDLEY_NON_NULL(...) -#endif -JSON_HEDLEY_DIAGNOSTIC_POP - -#if defined(JSON_HEDLEY_PRINTF_FORMAT) - #undef JSON_HEDLEY_PRINTF_FORMAT -#endif -#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO) - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check))) -#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO) - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check))) -#elif \ - JSON_HEDLEY_HAS_ATTRIBUTE(format) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check))) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0) - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check)) -#else - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) -#endif - -#if defined(JSON_HEDLEY_CONSTEXPR) - #undef JSON_HEDLEY_CONSTEXPR -#endif -#if defined(__cplusplus) - #if __cplusplus >= 201103L - #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr) - #endif -#endif -#if !defined(JSON_HEDLEY_CONSTEXPR) - #define JSON_HEDLEY_CONSTEXPR -#endif - -#if defined(JSON_HEDLEY_PREDICT) - #undef JSON_HEDLEY_PREDICT -#endif -#if defined(JSON_HEDLEY_LIKELY) - #undef JSON_HEDLEY_LIKELY -#endif -#if defined(JSON_HEDLEY_UNLIKELY) - #undef JSON_HEDLEY_UNLIKELY -#endif -#if defined(JSON_HEDLEY_UNPREDICTABLE) - #undef JSON_HEDLEY_UNPREDICTABLE -#endif -#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable) - #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr)) -#endif -#if \ - JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) -# define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability)) -# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability)) -# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability)) -# define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 ) -# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 ) -#elif \ - JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) -# define JSON_HEDLEY_PREDICT(expr, expected, probability) \ - (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))) -# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \ - (__extension__ ({ \ - double hedley_probability_ = (probability); \ - ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \ - })) -# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \ - (__extension__ ({ \ - double hedley_probability_ = (probability); \ - ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \ - })) -# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1) -# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0) -#else -# define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)) -# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr)) -# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr)) -# define JSON_HEDLEY_LIKELY(expr) (!!(expr)) -# define JSON_HEDLEY_UNLIKELY(expr) (!!(expr)) -#endif -#if !defined(JSON_HEDLEY_UNPREDICTABLE) - #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5) -#endif - -#if defined(JSON_HEDLEY_MALLOC) - #undef JSON_HEDLEY_MALLOC -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) - #define JSON_HEDLEY_MALLOC __attribute__((__malloc__)) -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) - #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory") -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(14, 0, 0) - #define JSON_HEDLEY_MALLOC __declspec(restrict) -#else - #define JSON_HEDLEY_MALLOC -#endif - -#if defined(JSON_HEDLEY_PURE) - #undef JSON_HEDLEY_PURE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) -# define JSON_HEDLEY_PURE __attribute__((__pure__)) -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) -# define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data") -#elif defined(__cplusplus) && \ - ( \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \ - ) -# define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;") -#else -# define JSON_HEDLEY_PURE -#endif - -#if defined(JSON_HEDLEY_CONST) - #undef JSON_HEDLEY_CONST -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(const) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) - #define JSON_HEDLEY_CONST __attribute__((__const__)) -#elif \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) - #define JSON_HEDLEY_CONST _Pragma("no_side_effect") -#else - #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE -#endif - -#if defined(JSON_HEDLEY_RESTRICT) - #undef JSON_HEDLEY_RESTRICT -#endif -#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus) - #define JSON_HEDLEY_RESTRICT restrict -#elif \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ - defined(__clang__) - #define JSON_HEDLEY_RESTRICT __restrict -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus) - #define JSON_HEDLEY_RESTRICT _Restrict -#else - #define JSON_HEDLEY_RESTRICT -#endif - -#if defined(JSON_HEDLEY_INLINE) - #undef JSON_HEDLEY_INLINE -#endif -#if \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ - (defined(__cplusplus) && (__cplusplus >= 199711L)) - #define JSON_HEDLEY_INLINE inline -#elif \ - defined(JSON_HEDLEY_GCC_VERSION) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0) - #define JSON_HEDLEY_INLINE __inline__ -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) - #define JSON_HEDLEY_INLINE __inline -#else - #define JSON_HEDLEY_INLINE -#endif - -#if defined(JSON_HEDLEY_ALWAYS_INLINE) - #undef JSON_HEDLEY_ALWAYS_INLINE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) -# define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) -# define JSON_HEDLEY_ALWAYS_INLINE __forceinline -#elif defined(__cplusplus) && \ - ( \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \ - ) -# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) -# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced") -#else -# define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE -#endif - -#if defined(JSON_HEDLEY_NEVER_INLINE) - #undef JSON_HEDLEY_NEVER_INLINE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) - #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__)) -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) - #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) -#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0) - #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline") -#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus) - #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never") -#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) - #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline)) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0) - #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) -#else - #define JSON_HEDLEY_NEVER_INLINE -#endif - -#if defined(JSON_HEDLEY_PRIVATE) - #undef JSON_HEDLEY_PRIVATE -#endif -#if defined(JSON_HEDLEY_PUBLIC) - #undef JSON_HEDLEY_PUBLIC -#endif -#if defined(JSON_HEDLEY_IMPORT) - #undef JSON_HEDLEY_IMPORT -#endif -#if defined(_WIN32) || defined(__CYGWIN__) -# define JSON_HEDLEY_PRIVATE -# define JSON_HEDLEY_PUBLIC __declspec(dllexport) -# define JSON_HEDLEY_IMPORT __declspec(dllimport) -#else -# if \ - JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ - ( \ - defined(__TI_EABI__) && \ - ( \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \ - ) \ - ) -# define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden"))) -# define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default"))) -# else -# define JSON_HEDLEY_PRIVATE -# define JSON_HEDLEY_PUBLIC -# endif -# define JSON_HEDLEY_IMPORT extern -#endif - -#if defined(JSON_HEDLEY_NO_THROW) - #undef JSON_HEDLEY_NO_THROW -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__)) -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) - #define JSON_HEDLEY_NO_THROW __declspec(nothrow) -#else - #define JSON_HEDLEY_NO_THROW -#endif - -#if defined(JSON_HEDLEY_FALL_THROUGH) - #undef JSON_HEDLEY_FALL_THROUGH -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) - #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__)) -#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough) - #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]]) -#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough) - #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]]) -#elif defined(__fallthrough) /* SAL */ - #define JSON_HEDLEY_FALL_THROUGH __fallthrough -#else - #define JSON_HEDLEY_FALL_THROUGH -#endif - -#if defined(JSON_HEDLEY_RETURNS_NON_NULL) - #undef JSON_HEDLEY_RETURNS_NON_NULL -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) - #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__)) -#elif defined(_Ret_notnull_) /* SAL */ - #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_ -#else - #define JSON_HEDLEY_RETURNS_NON_NULL -#endif - -#if defined(JSON_HEDLEY_ARRAY_PARAM) - #undef JSON_HEDLEY_ARRAY_PARAM -#endif -#if \ - defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ - !defined(__STDC_NO_VLA__) && \ - !defined(__cplusplus) && \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_TINYC_VERSION) - #define JSON_HEDLEY_ARRAY_PARAM(name) (name) -#else - #define JSON_HEDLEY_ARRAY_PARAM(name) -#endif - -#if defined(JSON_HEDLEY_IS_CONSTANT) - #undef JSON_HEDLEY_IS_CONSTANT -#endif -#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR) - #undef JSON_HEDLEY_REQUIRE_CONSTEXPR -#endif -/* JSON_HEDLEY_IS_CONSTEXPR_ is for - HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ -#if defined(JSON_HEDLEY_IS_CONSTEXPR_) - #undef JSON_HEDLEY_IS_CONSTEXPR_ -#endif -#if \ - JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) - #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr) -#endif -#if !defined(__cplusplus) -# if \ - JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24) -#if defined(__INTPTR_TYPE__) - #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*) -#else - #include - #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*) -#endif -# elif \ - ( \ - defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \ - !defined(JSON_HEDLEY_SUNPRO_VERSION) && \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_IAR_VERSION)) || \ - JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0) -#if defined(__INTPTR_TYPE__) - #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0) -#else - #include - #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0) -#endif -# elif \ - defined(JSON_HEDLEY_GCC_VERSION) || \ - defined(JSON_HEDLEY_INTEL_VERSION) || \ - defined(JSON_HEDLEY_TINYC_VERSION) || \ - defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \ - defined(JSON_HEDLEY_TI_CL2000_VERSION) || \ - defined(JSON_HEDLEY_TI_CL6X_VERSION) || \ - defined(JSON_HEDLEY_TI_CL7X_VERSION) || \ - defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \ - defined(__clang__) -# define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \ - sizeof(void) != \ - sizeof(*( \ - 1 ? \ - ((void*) ((expr) * 0L) ) : \ -((struct { char v[sizeof(void) * 2]; } *) 1) \ - ) \ - ) \ - ) -# endif -#endif -#if defined(JSON_HEDLEY_IS_CONSTEXPR_) - #if !defined(JSON_HEDLEY_IS_CONSTANT) - #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr) - #endif - #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1)) -#else - #if !defined(JSON_HEDLEY_IS_CONSTANT) - #define JSON_HEDLEY_IS_CONSTANT(expr) (0) - #endif - #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr) -#endif - -#if defined(JSON_HEDLEY_BEGIN_C_DECLS) - #undef JSON_HEDLEY_BEGIN_C_DECLS -#endif -#if defined(JSON_HEDLEY_END_C_DECLS) - #undef JSON_HEDLEY_END_C_DECLS -#endif -#if defined(JSON_HEDLEY_C_DECL) - #undef JSON_HEDLEY_C_DECL -#endif -#if defined(__cplusplus) - #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" { - #define JSON_HEDLEY_END_C_DECLS } - #define JSON_HEDLEY_C_DECL extern "C" -#else - #define JSON_HEDLEY_BEGIN_C_DECLS - #define JSON_HEDLEY_END_C_DECLS - #define JSON_HEDLEY_C_DECL -#endif - -#if defined(JSON_HEDLEY_STATIC_ASSERT) - #undef JSON_HEDLEY_STATIC_ASSERT -#endif -#if \ - !defined(__cplusplus) && ( \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \ - JSON_HEDLEY_HAS_FEATURE(c_static_assert) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - defined(_Static_assert) \ - ) -# define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message) -#elif \ - (defined(__cplusplus) && (__cplusplus >= 201103L)) || \ - JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) -# define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message)) -#else -# define JSON_HEDLEY_STATIC_ASSERT(expr, message) -#endif - -#if defined(JSON_HEDLEY_NULL) - #undef JSON_HEDLEY_NULL -#endif -#if defined(__cplusplus) - #if __cplusplus >= 201103L - #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr) - #elif defined(NULL) - #define JSON_HEDLEY_NULL NULL - #else - #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0) - #endif -#elif defined(NULL) - #define JSON_HEDLEY_NULL NULL -#else - #define JSON_HEDLEY_NULL ((void*) 0) -#endif - -#if defined(JSON_HEDLEY_MESSAGE) - #undef JSON_HEDLEY_MESSAGE -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") -# define JSON_HEDLEY_MESSAGE(msg) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ - JSON_HEDLEY_PRAGMA(message msg) \ - JSON_HEDLEY_DIAGNOSTIC_POP -#elif \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg) -#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg) -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg)) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg)) -#else -# define JSON_HEDLEY_MESSAGE(msg) -#endif - -#if defined(JSON_HEDLEY_WARNING) - #undef JSON_HEDLEY_WARNING -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") -# define JSON_HEDLEY_WARNING(msg) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ - JSON_HEDLEY_PRAGMA(clang warning msg) \ - JSON_HEDLEY_DIAGNOSTIC_POP -#elif \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg) -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) -# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg)) -#else -# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg) -#endif - -#if defined(JSON_HEDLEY_REQUIRE) - #undef JSON_HEDLEY_REQUIRE -#endif -#if defined(JSON_HEDLEY_REQUIRE_MSG) - #undef JSON_HEDLEY_REQUIRE_MSG -#endif -#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if) -# if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat") -# define JSON_HEDLEY_REQUIRE(expr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ - __attribute__((diagnose_if(!(expr), #expr, "error"))) \ - JSON_HEDLEY_DIAGNOSTIC_POP -# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ - __attribute__((diagnose_if(!(expr), msg, "error"))) \ - JSON_HEDLEY_DIAGNOSTIC_POP -# else -# define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error"))) -# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error"))) -# endif -#else -# define JSON_HEDLEY_REQUIRE(expr) -# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) -#endif - -#if defined(JSON_HEDLEY_FLAGS) - #undef JSON_HEDLEY_FLAGS -#endif -#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) - #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__)) -#endif - -#if defined(JSON_HEDLEY_FLAGS_CAST) - #undef JSON_HEDLEY_FLAGS_CAST -#endif -#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0) -# define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("warning(disable:188)") \ - ((T) (expr)); \ - JSON_HEDLEY_DIAGNOSTIC_POP \ - })) -#else -# define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr) -#endif - -#if defined(JSON_HEDLEY_EMPTY_BASES) - #undef JSON_HEDLEY_EMPTY_BASES -#endif -#if JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0) - #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases) -#else - #define JSON_HEDLEY_EMPTY_BASES -#endif - -/* Remaining macros are deprecated. */ - -#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK) - #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK -#endif -#if defined(__clang__) - #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0) -#else - #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE) - #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE -#endif -#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) - -#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE) - #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE -#endif -#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) - -#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN) - #undef JSON_HEDLEY_CLANG_HAS_BUILTIN -#endif -#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin) - -#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE) - #undef JSON_HEDLEY_CLANG_HAS_FEATURE -#endif -#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature) - -#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION) - #undef JSON_HEDLEY_CLANG_HAS_EXTENSION -#endif -#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension) - -#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE) - #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE -#endif -#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) - -#if defined(JSON_HEDLEY_CLANG_HAS_WARNING) - #undef JSON_HEDLEY_CLANG_HAS_WARNING -#endif -#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning) - -#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */ - - -// This file contains all internal macro definitions -// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them - -// exclude unsupported compilers -#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK) - #if defined(__clang__) - #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400 - #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" - #endif - #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER)) - #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800 - #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers" - #endif - #endif -#endif - -// C++ language standard detection -#if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L) - #define JSON_HAS_CPP_20 - #define JSON_HAS_CPP_17 - #define JSON_HAS_CPP_14 -#elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 - #define JSON_HAS_CPP_17 - #define JSON_HAS_CPP_14 -#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) - #define JSON_HAS_CPP_14 -#endif - -// disable float-equal warnings on GCC/clang -#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wfloat-equal" -#endif - -// disable documentation warnings on clang -#if defined(__clang__) - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wdocumentation" -#endif - -// allow to disable exceptions -#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION) - #define JSON_THROW(exception) throw exception - #define JSON_TRY try - #define JSON_CATCH(exception) catch(exception) - #define JSON_INTERNAL_CATCH(exception) catch(exception) -#else - #include - #define JSON_THROW(exception) std::abort() - #define JSON_TRY if(true) - #define JSON_CATCH(exception) if(false) - #define JSON_INTERNAL_CATCH(exception) if(false) -#endif - -// override exception macros -#if defined(JSON_THROW_USER) - #undef JSON_THROW - #define JSON_THROW JSON_THROW_USER -#endif -#if defined(JSON_TRY_USER) - #undef JSON_TRY - #define JSON_TRY JSON_TRY_USER -#endif -#if defined(JSON_CATCH_USER) - #undef JSON_CATCH - #define JSON_CATCH JSON_CATCH_USER - #undef JSON_INTERNAL_CATCH - #define JSON_INTERNAL_CATCH JSON_CATCH_USER -#endif -#if defined(JSON_INTERNAL_CATCH_USER) - #undef JSON_INTERNAL_CATCH - #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER -#endif - -// allow to override assert -#if !defined(JSON_ASSERT) - #include // assert - #define JSON_ASSERT(x) assert(x) -#endif - -/*! -@brief macro to briefly define a mapping between an enum and JSON -@def NLOHMANN_JSON_SERIALIZE_ENUM -@since version 3.4.0 -*/ -#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \ - template \ - inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \ - { \ - static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ - static const std::pair m[] = __VA_ARGS__; \ - auto it = std::find_if(std::begin(m), std::end(m), \ - [e](const std::pair& ej_pair) -> bool \ - { \ - return ej_pair.first == e; \ - }); \ - j = ((it != std::end(m)) ? it : std::begin(m))->second; \ - } \ - template \ - inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \ - { \ - static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ - static const std::pair m[] = __VA_ARGS__; \ - auto it = std::find_if(std::begin(m), std::end(m), \ - [&j](const std::pair& ej_pair) -> bool \ - { \ - return ej_pair.second == j; \ - }); \ - e = ((it != std::end(m)) ? it : std::begin(m))->first; \ - } - -// Ugly macros to avoid uglier copy-paste when specializing basic_json. They -// may be removed in the future once the class is split. - -#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \ - template class ObjectType, \ - template class ArrayType, \ - class StringType, class BooleanType, class NumberIntegerType, \ - class NumberUnsignedType, class NumberFloatType, \ - template class AllocatorType, \ - template class JSONSerializer, \ - class BinaryType> - -#define NLOHMANN_BASIC_JSON_TPL \ - basic_json - -// Macros to simplify conversion from/to types - -#define NLOHMANN_JSON_EXPAND( x ) x -#define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME -#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \ - NLOHMANN_JSON_PASTE64, \ - NLOHMANN_JSON_PASTE63, \ - NLOHMANN_JSON_PASTE62, \ - NLOHMANN_JSON_PASTE61, \ - NLOHMANN_JSON_PASTE60, \ - NLOHMANN_JSON_PASTE59, \ - NLOHMANN_JSON_PASTE58, \ - NLOHMANN_JSON_PASTE57, \ - NLOHMANN_JSON_PASTE56, \ - NLOHMANN_JSON_PASTE55, \ - NLOHMANN_JSON_PASTE54, \ - NLOHMANN_JSON_PASTE53, \ - NLOHMANN_JSON_PASTE52, \ - NLOHMANN_JSON_PASTE51, \ - NLOHMANN_JSON_PASTE50, \ - NLOHMANN_JSON_PASTE49, \ - NLOHMANN_JSON_PASTE48, \ - NLOHMANN_JSON_PASTE47, \ - NLOHMANN_JSON_PASTE46, \ - NLOHMANN_JSON_PASTE45, \ - NLOHMANN_JSON_PASTE44, \ - NLOHMANN_JSON_PASTE43, \ - NLOHMANN_JSON_PASTE42, \ - NLOHMANN_JSON_PASTE41, \ - NLOHMANN_JSON_PASTE40, \ - NLOHMANN_JSON_PASTE39, \ - NLOHMANN_JSON_PASTE38, \ - NLOHMANN_JSON_PASTE37, \ - NLOHMANN_JSON_PASTE36, \ - NLOHMANN_JSON_PASTE35, \ - NLOHMANN_JSON_PASTE34, \ - NLOHMANN_JSON_PASTE33, \ - NLOHMANN_JSON_PASTE32, \ - NLOHMANN_JSON_PASTE31, \ - NLOHMANN_JSON_PASTE30, \ - NLOHMANN_JSON_PASTE29, \ - NLOHMANN_JSON_PASTE28, \ - NLOHMANN_JSON_PASTE27, \ - NLOHMANN_JSON_PASTE26, \ - NLOHMANN_JSON_PASTE25, \ - NLOHMANN_JSON_PASTE24, \ - NLOHMANN_JSON_PASTE23, \ - NLOHMANN_JSON_PASTE22, \ - NLOHMANN_JSON_PASTE21, \ - NLOHMANN_JSON_PASTE20, \ - NLOHMANN_JSON_PASTE19, \ - NLOHMANN_JSON_PASTE18, \ - NLOHMANN_JSON_PASTE17, \ - NLOHMANN_JSON_PASTE16, \ - NLOHMANN_JSON_PASTE15, \ - NLOHMANN_JSON_PASTE14, \ - NLOHMANN_JSON_PASTE13, \ - NLOHMANN_JSON_PASTE12, \ - NLOHMANN_JSON_PASTE11, \ - NLOHMANN_JSON_PASTE10, \ - NLOHMANN_JSON_PASTE9, \ - NLOHMANN_JSON_PASTE8, \ - NLOHMANN_JSON_PASTE7, \ - NLOHMANN_JSON_PASTE6, \ - NLOHMANN_JSON_PASTE5, \ - NLOHMANN_JSON_PASTE4, \ - NLOHMANN_JSON_PASTE3, \ - NLOHMANN_JSON_PASTE2, \ - NLOHMANN_JSON_PASTE1)(__VA_ARGS__)) -#define NLOHMANN_JSON_PASTE2(func, v1) func(v1) -#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2) -#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3) -#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4) -#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5) -#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6) -#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7) -#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8) -#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9) -#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10) -#define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) -#define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) -#define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) -#define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) -#define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) -#define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -#define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) -#define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) -#define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) -#define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) -#define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) -#define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) -#define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) -#define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) -#define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) -#define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) -#define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) -#define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) -#define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) -#define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) -#define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) -#define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) -#define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) -#define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) -#define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) -#define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) -#define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) -#define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) -#define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) -#define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) -#define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) -#define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) -#define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) -#define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) -#define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) -#define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) -#define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) -#define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) -#define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) -#define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) -#define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) -#define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) -#define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) -#define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) -#define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) -#define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) -#define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) -#define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) -#define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) -#define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) -#define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) -#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) -#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) - -#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1; -#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1); - -/*! -@brief macro -@def NLOHMANN_DEFINE_TYPE_INTRUSIVE -@since version 3.9.0 -*/ -#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \ - friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } - -/*! -@brief macro -@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE -@since version 3.9.0 -*/ -#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \ - inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } - -#ifndef JSON_USE_IMPLICIT_CONVERSIONS - #define JSON_USE_IMPLICIT_CONVERSIONS 1 -#endif - -#if JSON_USE_IMPLICIT_CONVERSIONS - #define JSON_EXPLICIT -#else - #define JSON_EXPLICIT explicit -#endif - - -namespace nlohmann -{ -namespace detail -{ -//////////////// -// exceptions // -//////////////// - -/*! -@brief general exception of the @ref basic_json class - -This class is an extension of `std::exception` objects with a member @a id for -exception ids. It is used as the base class for all exceptions thrown by the -@ref basic_json class. This class can hence be used as "wildcard" to catch -exceptions. - -Subclasses: -- @ref parse_error for exceptions indicating a parse error -- @ref invalid_iterator for exceptions indicating errors with iterators -- @ref type_error for exceptions indicating executing a member function with - a wrong type -- @ref out_of_range for exceptions indicating access out of the defined range -- @ref other_error for exceptions indicating other library errors - -@internal -@note To have nothrow-copy-constructible exceptions, we internally use - `std::runtime_error` which can cope with arbitrary-length error messages. - Intermediate strings are built with static functions and then passed to - the actual constructor. -@endinternal - -@liveexample{The following code shows how arbitrary library exceptions can be -caught.,exception} - -@since version 3.0.0 -*/ -class exception : public std::exception -{ - public: - /// returns the explanatory string - JSON_HEDLEY_RETURNS_NON_NULL - const char* what() const noexcept override - { - return m.what(); - } - - /// the id of the exception - const int id; - - protected: - JSON_HEDLEY_NON_NULL(3) - exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} - - static std::string name(const std::string& ename, int id_) - { - return "[json.exception." + ename + "." + std::to_string(id_) + "] "; - } - - private: - /// an exception object as storage for error messages - std::runtime_error m; -}; - -/*! -@brief exception indicating a parse error - -This exception is thrown by the library when a parse error occurs. Parse errors -can occur during the deserialization of JSON text, CBOR, MessagePack, as well -as when using JSON Patch. - -Member @a byte holds the byte index of the last read character in the input -file. - -Exceptions have ids 1xx. - -name / id | example message | description ------------------------------- | --------------- | ------------------------- -json.exception.parse_error.101 | parse error at 2: unexpected end of input; expected string literal | This error indicates a syntax error while deserializing a JSON text. The error message describes that an unexpected token (character) was encountered, and the member @a byte indicates the error position. -json.exception.parse_error.102 | parse error at 14: missing or wrong low surrogate | JSON uses the `\uxxxx` format to describe Unicode characters. Code points above above 0xFFFF are split into two `\uxxxx` entries ("surrogate pairs"). This error indicates that the surrogate pair is incomplete or contains an invalid code point. -json.exception.parse_error.103 | parse error: code points above 0x10FFFF are invalid | Unicode supports code points up to 0x10FFFF. Code points above 0x10FFFF are invalid. -json.exception.parse_error.104 | parse error: JSON patch must be an array of objects | [RFC 6902](https://tools.ietf.org/html/rfc6902) requires a JSON Patch document to be a JSON document that represents an array of objects. -json.exception.parse_error.105 | parse error: operation must have string member 'op' | An operation of a JSON Patch document must contain exactly one "op" member, whose value indicates the operation to perform. Its value must be one of "add", "remove", "replace", "move", "copy", or "test"; other values are errors. -json.exception.parse_error.106 | parse error: array index '01' must not begin with '0' | An array index in a JSON Pointer ([RFC 6901](https://tools.ietf.org/html/rfc6901)) may be `0` or any number without a leading `0`. -json.exception.parse_error.107 | parse error: JSON pointer must be empty or begin with '/' - was: 'foo' | A JSON Pointer must be a Unicode string containing a sequence of zero or more reference tokens, each prefixed by a `/` character. -json.exception.parse_error.108 | parse error: escape character '~' must be followed with '0' or '1' | In a JSON Pointer, only `~0` and `~1` are valid escape sequences. -json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number. -json.exception.parse_error.110 | parse error at 1: cannot read 2 bytes from vector | When parsing CBOR or MessagePack, the byte vector ends before the complete value has been read. -json.exception.parse_error.112 | parse error at 1: error reading CBOR; last byte: 0xF8 | Not all types of CBOR or MessagePack are supported. This exception occurs if an unsupported byte was read. -json.exception.parse_error.113 | parse error at 2: expected a CBOR string; last byte: 0x98 | While parsing a map key, a value that is not a string has been read. -json.exception.parse_error.114 | parse error: Unsupported BSON record type 0x0F | The parsing of the corresponding BSON record type is not implemented (yet). -json.exception.parse_error.115 | parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1A | A UBJSON high-precision number could not be parsed. - -@note For an input with n bytes, 1 is the index of the first character and n+1 - is the index of the terminating null byte or the end of file. This also - holds true when reading a byte vector (CBOR or MessagePack). - -@liveexample{The following code shows how a `parse_error` exception can be -caught.,parse_error} - -@sa - @ref exception for the base class of the library exceptions -@sa - @ref invalid_iterator for exceptions indicating errors with iterators -@sa - @ref type_error for exceptions indicating executing a member function with - a wrong type -@sa - @ref out_of_range for exceptions indicating access out of the defined range -@sa - @ref other_error for exceptions indicating other library errors - -@since version 3.0.0 -*/ -class parse_error : public exception -{ - public: - /*! - @brief create a parse error exception - @param[in] id_ the id of the exception - @param[in] pos the position where the error occurred (or with - chars_read_total=0 if the position cannot be - determined) - @param[in] what_arg the explanatory string - @return parse_error object - */ - static parse_error create(int id_, const position_t& pos, const std::string& what_arg) - { - std::string w = exception::name("parse_error", id_) + "parse error" + - position_string(pos) + ": " + what_arg; - return parse_error(id_, pos.chars_read_total, w.c_str()); - } - - static parse_error create(int id_, std::size_t byte_, const std::string& what_arg) - { - std::string w = exception::name("parse_error", id_) + "parse error" + - (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") + - ": " + what_arg; - return parse_error(id_, byte_, w.c_str()); - } - - /*! - @brief byte index of the parse error - - The byte index of the last read character in the input file. - - @note For an input with n bytes, 1 is the index of the first character and - n+1 is the index of the terminating null byte or the end of file. - This also holds true when reading a byte vector (CBOR or MessagePack). - */ - const std::size_t byte; - - private: - parse_error(int id_, std::size_t byte_, const char* what_arg) - : exception(id_, what_arg), byte(byte_) {} - - static std::string position_string(const position_t& pos) - { - return " at line " + std::to_string(pos.lines_read + 1) + - ", column " + std::to_string(pos.chars_read_current_line); - } -}; - -/*! -@brief exception indicating errors with iterators - -This exception is thrown if iterators passed to a library function do not match -the expected semantics. - -Exceptions have ids 2xx. - -name / id | example message | description ------------------------------------ | --------------- | ------------------------- -json.exception.invalid_iterator.201 | iterators are not compatible | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid. -json.exception.invalid_iterator.202 | iterator does not fit current value | In an erase or insert function, the passed iterator @a pos does not belong to the JSON value for which the function was called. It hence does not define a valid position for the deletion/insertion. -json.exception.invalid_iterator.203 | iterators do not fit current value | Either iterator passed to function @ref erase(IteratorType first, IteratorType last) does not belong to the JSON value from which values shall be erased. It hence does not define a valid range to delete values from. -json.exception.invalid_iterator.204 | iterators out of range | When an iterator range for a primitive type (number, boolean, or string) is passed to a constructor or an erase function, this range has to be exactly (@ref begin(), @ref end()), because this is the only way the single stored value is expressed. All other ranges are invalid. -json.exception.invalid_iterator.205 | iterator out of range | When an iterator for a primitive type (number, boolean, or string) is passed to an erase function, the iterator has to be the @ref begin() iterator, because it is the only way to address the stored value. All other iterators are invalid. -json.exception.invalid_iterator.206 | cannot construct with iterators from null | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) belong to a JSON null value and hence to not define a valid range. -json.exception.invalid_iterator.207 | cannot use key() for non-object iterators | The key() member function can only be used on iterators belonging to a JSON object, because other types do not have a concept of a key. -json.exception.invalid_iterator.208 | cannot use operator[] for object iterators | The operator[] to specify a concrete offset cannot be used on iterators belonging to a JSON object, because JSON objects are unordered. -json.exception.invalid_iterator.209 | cannot use offsets with object iterators | The offset operators (+, -, +=, -=) cannot be used on iterators belonging to a JSON object, because JSON objects are unordered. -json.exception.invalid_iterator.210 | iterators do not fit | The iterator range passed to the insert function are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid. -json.exception.invalid_iterator.211 | passed iterators may not belong to container | The iterator range passed to the insert function must not be a subrange of the container to insert to. -json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container. -json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered. -json.exception.invalid_iterator.214 | cannot get value | Cannot get value for iterator: Either the iterator belongs to a null value or it is an iterator to a primitive type (number, boolean, or string), but the iterator is different to @ref begin(). - -@liveexample{The following code shows how an `invalid_iterator` exception can be -caught.,invalid_iterator} - -@sa - @ref exception for the base class of the library exceptions -@sa - @ref parse_error for exceptions indicating a parse error -@sa - @ref type_error for exceptions indicating executing a member function with - a wrong type -@sa - @ref out_of_range for exceptions indicating access out of the defined range -@sa - @ref other_error for exceptions indicating other library errors - -@since version 3.0.0 -*/ -class invalid_iterator : public exception -{ - public: - static invalid_iterator create(int id_, const std::string& what_arg) - { - std::string w = exception::name("invalid_iterator", id_) + what_arg; - return invalid_iterator(id_, w.c_str()); - } - - private: - JSON_HEDLEY_NON_NULL(3) - invalid_iterator(int id_, const char* what_arg) - : exception(id_, what_arg) {} -}; - -/*! -@brief exception indicating executing a member function with a wrong type - -This exception is thrown in case of a type error; that is, a library function is -executed on a JSON value whose type does not match the expected semantics. - -Exceptions have ids 3xx. - -name / id | example message | description ------------------------------ | --------------- | ------------------------- -json.exception.type_error.301 | cannot create object from initializer list | To create an object from an initializer list, the initializer list must consist only of a list of pairs whose first element is a string. When this constraint is violated, an array is created instead. -json.exception.type_error.302 | type must be object, but is array | During implicit or explicit value conversion, the JSON type must be compatible to the target type. For instance, a JSON string can only be converted into string types, but not into numbers or boolean types. -json.exception.type_error.303 | incompatible ReferenceType for get_ref, actual type is object | To retrieve a reference to a value stored in a @ref basic_json object with @ref get_ref, the type of the reference must match the value type. For instance, for a JSON array, the @a ReferenceType must be @ref array_t &. -json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types. -json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types. -json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types. -json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types. -json.exception.type_error.308 | cannot use push_back() with string | The @ref push_back() and @ref operator+= member functions can only be executed for certain JSON types. -json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types. -json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types. -json.exception.type_error.311 | cannot use emplace_back() with string | The @ref emplace_back() member function can only be executed for certain JSON types. -json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types. -json.exception.type_error.313 | invalid value to unflatten | The @ref unflatten function converts an object whose keys are JSON Pointers back into an arbitrary nested JSON value. The JSON Pointers must not overlap, because then the resulting value would not be well defined. -json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers. -json.exception.type_error.315 | values in object must be primitive | The @ref unflatten function only works for an object whose keys are JSON Pointers and whose values are primitive. -json.exception.type_error.316 | invalid UTF-8 byte at index 10: 0x7E | The @ref dump function only works with UTF-8 encoded strings; that is, if you assign a `std::string` to a JSON value, make sure it is UTF-8 encoded. | -json.exception.type_error.317 | JSON value cannot be serialized to requested format | The dynamic type of the object cannot be represented in the requested serialization format (e.g. a raw `true` or `null` JSON object cannot be serialized to BSON) | - -@liveexample{The following code shows how a `type_error` exception can be -caught.,type_error} - -@sa - @ref exception for the base class of the library exceptions -@sa - @ref parse_error for exceptions indicating a parse error -@sa - @ref invalid_iterator for exceptions indicating errors with iterators -@sa - @ref out_of_range for exceptions indicating access out of the defined range -@sa - @ref other_error for exceptions indicating other library errors - -@since version 3.0.0 -*/ -class type_error : public exception -{ - public: - static type_error create(int id_, const std::string& what_arg) - { - std::string w = exception::name("type_error", id_) + what_arg; - return type_error(id_, w.c_str()); - } - - private: - JSON_HEDLEY_NON_NULL(3) - type_error(int id_, const char* what_arg) : exception(id_, what_arg) {} -}; - -/*! -@brief exception indicating access out of the defined range - -This exception is thrown in case a library function is called on an input -parameter that exceeds the expected range, for instance in case of array -indices or nonexisting object keys. - -Exceptions have ids 4xx. - -name / id | example message | description -------------------------------- | --------------- | ------------------------- -json.exception.out_of_range.401 | array index 3 is out of range | The provided array index @a i is larger than @a size-1. -json.exception.out_of_range.402 | array index '-' (3) is out of range | The special array index `-` in a JSON Pointer never describes a valid element of the array, but the index past the end. That is, it can only be used to add elements at this position, but not to read it. -json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object. -json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved. -json.exception.out_of_range.405 | JSON pointer has no parent | The JSON Patch operations 'remove' and 'add' can not be applied to the root element of the JSON value. -json.exception.out_of_range.406 | number overflow parsing '10E1000' | A parsed number could not be stored as without changing it to NaN or INF. -json.exception.out_of_range.407 | number overflow serializing '9223372036854775808' | UBJSON and BSON only support integer numbers up to 9223372036854775807. (until version 3.8.0) | -json.exception.out_of_range.408 | excessive array size: 8658170730974374167 | The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. | -json.exception.out_of_range.409 | BSON key cannot contain code point U+0000 (at byte 2) | Key identifiers to be serialized to BSON cannot contain code point U+0000, since the key is stored as zero-terminated c-string | - -@liveexample{The following code shows how an `out_of_range` exception can be -caught.,out_of_range} - -@sa - @ref exception for the base class of the library exceptions -@sa - @ref parse_error for exceptions indicating a parse error -@sa - @ref invalid_iterator for exceptions indicating errors with iterators -@sa - @ref type_error for exceptions indicating executing a member function with - a wrong type -@sa - @ref other_error for exceptions indicating other library errors - -@since version 3.0.0 -*/ -class out_of_range : public exception -{ - public: - static out_of_range create(int id_, const std::string& what_arg) - { - std::string w = exception::name("out_of_range", id_) + what_arg; - return out_of_range(id_, w.c_str()); - } - - private: - JSON_HEDLEY_NON_NULL(3) - out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {} -}; - -/*! -@brief exception indicating other library errors - -This exception is thrown in case of errors that cannot be classified with the -other exception types. - -Exceptions have ids 5xx. - -name / id | example message | description ------------------------------- | --------------- | ------------------------- -json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed. - -@sa - @ref exception for the base class of the library exceptions -@sa - @ref parse_error for exceptions indicating a parse error -@sa - @ref invalid_iterator for exceptions indicating errors with iterators -@sa - @ref type_error for exceptions indicating executing a member function with - a wrong type -@sa - @ref out_of_range for exceptions indicating access out of the defined range - -@liveexample{The following code shows how an `other_error` exception can be -caught.,other_error} - -@since version 3.0.0 -*/ -class other_error : public exception -{ - public: - static other_error create(int id_, const std::string& what_arg) - { - std::string w = exception::name("other_error", id_) + what_arg; - return other_error(id_, w.c_str()); - } - - private: - JSON_HEDLEY_NON_NULL(3) - other_error(int id_, const char* what_arg) : exception(id_, what_arg) {} -}; -} // namespace detail -} // namespace nlohmann - -// #include - -// #include - - -#include // size_t -#include // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type - -namespace nlohmann -{ -namespace detail -{ -// alias templates to reduce boilerplate -template -using enable_if_t = typename std::enable_if::type; - -template -using uncvref_t = typename std::remove_cv::type>::type; - -// implementation of C++14 index_sequence and affiliates -// source: https://stackoverflow.com/a/32223343 -template -struct index_sequence -{ - using type = index_sequence; - using value_type = std::size_t; - static constexpr std::size_t size() noexcept - { - return sizeof...(Ints); - } -}; - -template -struct merge_and_renumber; - -template -struct merge_and_renumber, index_sequence> - : index_sequence < I1..., (sizeof...(I1) + I2)... > {}; - -template -struct make_index_sequence - : merge_and_renumber < typename make_index_sequence < N / 2 >::type, - typename make_index_sequence < N - N / 2 >::type > {}; - -template<> struct make_index_sequence<0> : index_sequence<> {}; -template<> struct make_index_sequence<1> : index_sequence<0> {}; - -template -using index_sequence_for = make_index_sequence; - -// dispatch utility (taken from ranges-v3) -template struct priority_tag : priority_tag < N - 1 > {}; -template<> struct priority_tag<0> {}; - -// taken from ranges-v3 -template -struct static_const -{ - static constexpr T value{}; -}; - -template -constexpr T static_const::value; -} // namespace detail -} // namespace nlohmann - -// #include - - -#include // numeric_limits -#include // false_type, is_constructible, is_integral, is_same, true_type -#include // declval - -// #include - - -#include // random_access_iterator_tag - -// #include - - -namespace nlohmann -{ -namespace detail -{ -template struct make_void -{ - using type = void; -}; -template using void_t = typename make_void::type; -} // namespace detail -} // namespace nlohmann - -// #include - - -namespace nlohmann -{ -namespace detail -{ -template -struct iterator_types {}; - -template -struct iterator_types < - It, - void_t> -{ - using difference_type = typename It::difference_type; - using value_type = typename It::value_type; - using pointer = typename It::pointer; - using reference = typename It::reference; - using iterator_category = typename It::iterator_category; -}; - -// This is required as some compilers implement std::iterator_traits in a way that -// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341. -template -struct iterator_traits -{ -}; - -template -struct iterator_traits < T, enable_if_t < !std::is_pointer::value >> - : iterator_types -{ -}; - -template -struct iterator_traits::value>> -{ - using iterator_category = std::random_access_iterator_tag; - using value_type = T; - using difference_type = ptrdiff_t; - using pointer = T*; - using reference = T&; -}; -} // namespace detail -} // namespace nlohmann - -// #include - -// #include - -// #include - - -#include - -// #include - - -// https://en.cppreference.com/w/cpp/experimental/is_detected -namespace nlohmann -{ -namespace detail -{ -struct nonesuch -{ - nonesuch() = delete; - ~nonesuch() = delete; - nonesuch(nonesuch const&) = delete; - nonesuch(nonesuch const&&) = delete; - void operator=(nonesuch const&) = delete; - void operator=(nonesuch&&) = delete; -}; - -template class Op, - class... Args> -struct detector -{ - using value_t = std::false_type; - using type = Default; -}; - -template class Op, class... Args> -struct detector>, Op, Args...> -{ - using value_t = std::true_type; - using type = Op; -}; - -template class Op, class... Args> -using is_detected = typename detector::value_t; - -template class Op, class... Args> -using detected_t = typename detector::type; - -template class Op, class... Args> -using detected_or = detector; - -template class Op, class... Args> -using detected_or_t = typename detected_or::type; - -template class Op, class... Args> -using is_detected_exact = std::is_same>; - -template class Op, class... Args> -using is_detected_convertible = - std::is_convertible, To>; -} // namespace detail -} // namespace nlohmann - -// #include -#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_ -#define INCLUDE_NLOHMANN_JSON_FWD_HPP_ - -#include // int64_t, uint64_t -#include // map -#include // allocator -#include // string -#include // vector - -/*! -@brief namespace for Niels Lohmann -@see https://github.com/nlohmann -@since version 1.0.0 -*/ -namespace nlohmann -{ -/*! -@brief default JSONSerializer template argument - -This serializer ignores the template arguments and uses ADL -([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl)) -for serialization. -*/ -template -struct adl_serializer; - -template class ObjectType = - std::map, - template class ArrayType = std::vector, - class StringType = std::string, class BooleanType = bool, - class NumberIntegerType = std::int64_t, - class NumberUnsignedType = std::uint64_t, - class NumberFloatType = double, - template class AllocatorType = std::allocator, - template class JSONSerializer = - adl_serializer, - class BinaryType = std::vector> -class basic_json; - -/*! -@brief JSON Pointer - -A JSON pointer defines a string syntax for identifying a specific value -within a JSON document. It can be used with functions `at` and -`operator[]`. Furthermore, JSON pointers are the base for JSON patches. - -@sa [RFC 6901](https://tools.ietf.org/html/rfc6901) - -@since version 2.0.0 -*/ -template -class json_pointer; - -/*! -@brief default JSON class - -This type is the default specialization of the @ref basic_json class which -uses the standard template types. - -@since version 1.0.0 -*/ -using json = basic_json<>; - -template -struct ordered_map; - -/*! -@brief ordered JSON class - -This type preserves the insertion order of object keys. - -@since version 3.9.0 -*/ -using ordered_json = basic_json; - -} // namespace nlohmann - -#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_ - - -namespace nlohmann -{ -/*! -@brief detail namespace with internal helper functions - -This namespace collects functions that should not be exposed, -implementations of some @ref basic_json methods, and meta-programming helpers. - -@since version 2.1.0 -*/ -namespace detail -{ -///////////// -// helpers // -///////////// - -// Note to maintainers: -// -// Every trait in this file expects a non CV-qualified type. -// The only exceptions are in the 'aliases for detected' section -// (i.e. those of the form: decltype(T::member_function(std::declval()))) -// -// In this case, T has to be properly CV-qualified to constraint the function arguments -// (e.g. to_json(BasicJsonType&, const T&)) - -template struct is_basic_json : std::false_type {}; - -NLOHMANN_BASIC_JSON_TPL_DECLARATION -struct is_basic_json : std::true_type {}; - -////////////////////// -// json_ref helpers // -////////////////////// - -template -class json_ref; - -template -struct is_json_ref : std::false_type {}; - -template -struct is_json_ref> : std::true_type {}; - -////////////////////////// -// aliases for detected // -////////////////////////// - -template -using mapped_type_t = typename T::mapped_type; - -template -using key_type_t = typename T::key_type; - -template -using value_type_t = typename T::value_type; - -template -using difference_type_t = typename T::difference_type; - -template -using pointer_t = typename T::pointer; - -template -using reference_t = typename T::reference; - -template -using iterator_category_t = typename T::iterator_category; - -template -using iterator_t = typename T::iterator; - -template -using to_json_function = decltype(T::to_json(std::declval()...)); - -template -using from_json_function = decltype(T::from_json(std::declval()...)); - -template -using get_template_function = decltype(std::declval().template get()); - -// trait checking if JSONSerializer::from_json(json const&, udt&) exists -template -struct has_from_json : std::false_type {}; - -// trait checking if j.get is valid -// use this trait instead of std::is_constructible or std::is_convertible, -// both rely on, or make use of implicit conversions, and thus fail when T -// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958) -template -struct is_getable -{ - static constexpr bool value = is_detected::value; -}; - -template -struct has_from_json < BasicJsonType, T, - enable_if_t < !is_basic_json::value >> -{ - using serializer = typename BasicJsonType::template json_serializer; - - static constexpr bool value = - is_detected_exact::value; -}; - -// This trait checks if JSONSerializer::from_json(json const&) exists -// this overload is used for non-default-constructible user-defined-types -template -struct has_non_default_from_json : std::false_type {}; - -template -struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> -{ - using serializer = typename BasicJsonType::template json_serializer; - - static constexpr bool value = - is_detected_exact::value; -}; - -// This trait checks if BasicJsonType::json_serializer::to_json exists -// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion. -template -struct has_to_json : std::false_type {}; - -template -struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> -{ - using serializer = typename BasicJsonType::template json_serializer; - - static constexpr bool value = - is_detected_exact::value; -}; - - -/////////////////// -// is_ functions // -/////////////////// - -template -struct is_iterator_traits : std::false_type {}; - -template -struct is_iterator_traits> -{ - private: - using traits = iterator_traits; - - public: - static constexpr auto value = - is_detected::value && - is_detected::value && - is_detected::value && - is_detected::value && - is_detected::value; -}; - -// source: https://stackoverflow.com/a/37193089/4116453 - -template -struct is_complete_type : std::false_type {}; - -template -struct is_complete_type : std::true_type {}; - -template -struct is_compatible_object_type_impl : std::false_type {}; - -template -struct is_compatible_object_type_impl < - BasicJsonType, CompatibleObjectType, - enable_if_t < is_detected::value&& - is_detected::value >> -{ - - using object_t = typename BasicJsonType::object_t; - - // macOS's is_constructible does not play well with nonesuch... - static constexpr bool value = - std::is_constructible::value && - std::is_constructible::value; -}; - -template -struct is_compatible_object_type - : is_compatible_object_type_impl {}; - -template -struct is_constructible_object_type_impl : std::false_type {}; - -template -struct is_constructible_object_type_impl < - BasicJsonType, ConstructibleObjectType, - enable_if_t < is_detected::value&& - is_detected::value >> -{ - using object_t = typename BasicJsonType::object_t; - - static constexpr bool value = - (std::is_default_constructible::value && - (std::is_move_assignable::value || - std::is_copy_assignable::value) && - (std::is_constructible::value && - std::is_same < - typename object_t::mapped_type, - typename ConstructibleObjectType::mapped_type >::value)) || - (has_from_json::value || - has_non_default_from_json < - BasicJsonType, - typename ConstructibleObjectType::mapped_type >::value); -}; - -template -struct is_constructible_object_type - : is_constructible_object_type_impl {}; - -template -struct is_compatible_string_type_impl : std::false_type {}; - -template -struct is_compatible_string_type_impl < - BasicJsonType, CompatibleStringType, - enable_if_t::value >> -{ - static constexpr auto value = - std::is_constructible::value; -}; - -template -struct is_compatible_string_type - : is_compatible_string_type_impl {}; - -template -struct is_constructible_string_type_impl : std::false_type {}; - -template -struct is_constructible_string_type_impl < - BasicJsonType, ConstructibleStringType, - enable_if_t::value >> -{ - static constexpr auto value = - std::is_constructible::value; -}; - -template -struct is_constructible_string_type - : is_constructible_string_type_impl {}; - -template -struct is_compatible_array_type_impl : std::false_type {}; - -template -struct is_compatible_array_type_impl < - BasicJsonType, CompatibleArrayType, - enable_if_t < is_detected::value&& - is_detected::value&& -// This is needed because json_reverse_iterator has a ::iterator type... -// Therefore it is detected as a CompatibleArrayType. -// The real fix would be to have an Iterable concept. - !is_iterator_traits < - iterator_traits>::value >> -{ - static constexpr bool value = - std::is_constructible::value; -}; - -template -struct is_compatible_array_type - : is_compatible_array_type_impl {}; - -template -struct is_constructible_array_type_impl : std::false_type {}; - -template -struct is_constructible_array_type_impl < - BasicJsonType, ConstructibleArrayType, - enable_if_t::value >> - : std::true_type {}; - -template -struct is_constructible_array_type_impl < - BasicJsonType, ConstructibleArrayType, - enable_if_t < !std::is_same::value&& - std::is_default_constructible::value&& -(std::is_move_assignable::value || - std::is_copy_assignable::value)&& -is_detected::value&& -is_detected::value&& -is_complete_type < -detected_t>::value >> -{ - static constexpr bool value = - // This is needed because json_reverse_iterator has a ::iterator type, - // furthermore, std::back_insert_iterator (and other iterators) have a - // base class `iterator`... Therefore it is detected as a - // ConstructibleArrayType. The real fix would be to have an Iterable - // concept. - !is_iterator_traits>::value && - - (std::is_same::value || - has_from_json::value || - has_non_default_from_json < - BasicJsonType, typename ConstructibleArrayType::value_type >::value); -}; - -template -struct is_constructible_array_type - : is_constructible_array_type_impl {}; - -template -struct is_compatible_integer_type_impl : std::false_type {}; - -template -struct is_compatible_integer_type_impl < - RealIntegerType, CompatibleNumberIntegerType, - enable_if_t < std::is_integral::value&& - std::is_integral::value&& - !std::is_same::value >> -{ - // is there an assert somewhere on overflows? - using RealLimits = std::numeric_limits; - using CompatibleLimits = std::numeric_limits; - - static constexpr auto value = - std::is_constructible::value && - CompatibleLimits::is_integer && - RealLimits::is_signed == CompatibleLimits::is_signed; -}; - -template -struct is_compatible_integer_type - : is_compatible_integer_type_impl {}; - -template -struct is_compatible_type_impl: std::false_type {}; - -template -struct is_compatible_type_impl < - BasicJsonType, CompatibleType, - enable_if_t::value >> -{ - static constexpr bool value = - has_to_json::value; -}; - -template -struct is_compatible_type - : is_compatible_type_impl {}; - -// https://en.cppreference.com/w/cpp/types/conjunction -template struct conjunction : std::true_type { }; -template struct conjunction : B1 { }; -template -struct conjunction -: std::conditional, B1>::type {}; - -template -struct is_constructible_tuple : std::false_type {}; - -template -struct is_constructible_tuple> : conjunction...> {}; -} // namespace detail -} // namespace nlohmann - -// #include - - -#include // array -#include // size_t -#include // uint8_t -#include // string - -namespace nlohmann -{ -namespace detail -{ -/////////////////////////// -// JSON type enumeration // -/////////////////////////// - -/*! -@brief the JSON type enumeration - -This enumeration collects the different JSON types. It is internally used to -distinguish the stored values, and the functions @ref basic_json::is_null(), -@ref basic_json::is_object(), @ref basic_json::is_array(), -@ref basic_json::is_string(), @ref basic_json::is_boolean(), -@ref basic_json::is_number() (with @ref basic_json::is_number_integer(), -@ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()), -@ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and -@ref basic_json::is_structured() rely on it. - -@note There are three enumeration entries (number_integer, number_unsigned, and -number_float), because the library distinguishes these three types for numbers: -@ref basic_json::number_unsigned_t is used for unsigned integers, -@ref basic_json::number_integer_t is used for signed integers, and -@ref basic_json::number_float_t is used for floating-point numbers or to -approximate integers which do not fit in the limits of their respective type. - -@sa @ref basic_json::basic_json(const value_t value_type) -- create a JSON -value with the default value for a given type - -@since version 1.0.0 -*/ -enum class value_t : std::uint8_t -{ - null, ///< null value - object, ///< object (unordered set of name/value pairs) - array, ///< array (ordered collection of values) - string, ///< string value - boolean, ///< boolean value - number_integer, ///< number value (signed integer) - number_unsigned, ///< number value (unsigned integer) - number_float, ///< number value (floating-point) - binary, ///< binary array (ordered collection of bytes) - discarded ///< discarded by the parser callback function -}; - -/*! -@brief comparison operator for JSON types - -Returns an ordering that is similar to Python: -- order: null < boolean < number < object < array < string < binary -- furthermore, each type is not smaller than itself -- discarded values are not comparable -- binary is represented as a b"" string in python and directly comparable to a - string; however, making a binary array directly comparable with a string would - be surprising behavior in a JSON file. - -@since version 1.0.0 -*/ -inline bool operator<(const value_t lhs, const value_t rhs) noexcept -{ - static constexpr std::array order = {{ - 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */, - 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */, - 6 /* binary */ - } - }; - - const auto l_index = static_cast(lhs); - const auto r_index = static_cast(rhs); - return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index]; -} -} // namespace detail -} // namespace nlohmann - - -namespace nlohmann -{ -namespace detail -{ -template -void from_json(const BasicJsonType& j, typename std::nullptr_t& n) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_null())) - { - JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name()))); - } - n = nullptr; -} - -// overloads for basic_json template parameters -template < typename BasicJsonType, typename ArithmeticType, - enable_if_t < std::is_arithmetic::value&& - !std::is_same::value, - int > = 0 > -void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val) -{ - switch (static_cast(j)) - { - case value_t::number_unsigned: - { - val = static_cast(*j.template get_ptr()); - break; - } - case value_t::number_integer: - { - val = static_cast(*j.template get_ptr()); - break; - } - case value_t::number_float: - { - val = static_cast(*j.template get_ptr()); - break; - } - - default: - JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()))); - } -} - -template -void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_boolean())) - { - JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name()))); - } - b = *j.template get_ptr(); -} - -template -void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_string())) - { - JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()))); - } - s = *j.template get_ptr(); -} - -template < - typename BasicJsonType, typename ConstructibleStringType, - enable_if_t < - is_constructible_string_type::value&& - !std::is_same::value, - int > = 0 > -void from_json(const BasicJsonType& j, ConstructibleStringType& s) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_string())) - { - JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()))); - } - - s = *j.template get_ptr(); -} - -template -void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val) -{ - get_arithmetic_value(j, val); -} - -template -void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val) -{ - get_arithmetic_value(j, val); -} - -template -void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val) -{ - get_arithmetic_value(j, val); -} - -template::value, int> = 0> -void from_json(const BasicJsonType& j, EnumType& e) -{ - typename std::underlying_type::type val; - get_arithmetic_value(j, val); - e = static_cast(val); -} - -// forward_list doesn't have an insert method -template::value, int> = 0> -void from_json(const BasicJsonType& j, std::forward_list& l) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_array())) - { - JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()))); - } - l.clear(); - std::transform(j.rbegin(), j.rend(), - std::front_inserter(l), [](const BasicJsonType & i) - { - return i.template get(); - }); -} - -// valarray doesn't have an insert method -template::value, int> = 0> -void from_json(const BasicJsonType& j, std::valarray& l) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_array())) - { - JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()))); - } - l.resize(j.size()); - std::transform(j.begin(), j.end(), std::begin(l), - [](const BasicJsonType & elem) - { - return elem.template get(); - }); -} - -template -auto from_json(const BasicJsonType& j, T (&arr)[N]) --> decltype(j.template get(), void()) -{ - for (std::size_t i = 0; i < N; ++i) - { - arr[i] = j.at(i).template get(); - } -} - -template -void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/) -{ - arr = *j.template get_ptr(); -} - -template -auto from_json_array_impl(const BasicJsonType& j, std::array& arr, - priority_tag<2> /*unused*/) --> decltype(j.template get(), void()) -{ - for (std::size_t i = 0; i < N; ++i) - { - arr[i] = j.at(i).template get(); - } -} - -template -auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/) --> decltype( - arr.reserve(std::declval()), - j.template get(), - void()) -{ - using std::end; - - ConstructibleArrayType ret; - ret.reserve(j.size()); - std::transform(j.begin(), j.end(), - std::inserter(ret, end(ret)), [](const BasicJsonType & i) - { - // get() returns *this, this won't call a from_json - // method when value_type is BasicJsonType - return i.template get(); - }); - arr = std::move(ret); -} - -template -void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, - priority_tag<0> /*unused*/) -{ - using std::end; - - ConstructibleArrayType ret; - std::transform( - j.begin(), j.end(), std::inserter(ret, end(ret)), - [](const BasicJsonType & i) - { - // get() returns *this, this won't call a from_json - // method when value_type is BasicJsonType - return i.template get(); - }); - arr = std::move(ret); -} - -template < typename BasicJsonType, typename ConstructibleArrayType, - enable_if_t < - is_constructible_array_type::value&& - !is_constructible_object_type::value&& - !is_constructible_string_type::value&& - !std::is_same::value&& - !is_basic_json::value, - int > = 0 > -auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr) --> decltype(from_json_array_impl(j, arr, priority_tag<3> {}), -j.template get(), -void()) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_array())) - { - JSON_THROW(type_error::create(302, "type must be array, but is " + - std::string(j.type_name()))); - } - - from_json_array_impl(j, arr, priority_tag<3> {}); -} - -template -void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_binary())) - { - JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name()))); - } - - bin = *j.template get_ptr(); -} - -template::value, int> = 0> -void from_json(const BasicJsonType& j, ConstructibleObjectType& obj) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_object())) - { - JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name()))); - } - - ConstructibleObjectType ret; - auto inner_object = j.template get_ptr(); - using value_type = typename ConstructibleObjectType::value_type; - std::transform( - inner_object->begin(), inner_object->end(), - std::inserter(ret, ret.begin()), - [](typename BasicJsonType::object_t::value_type const & p) - { - return value_type(p.first, p.second.template get()); - }); - obj = std::move(ret); -} - -// overload for arithmetic types, not chosen for basic_json template arguments -// (BooleanType, etc..); note: Is it really necessary to provide explicit -// overloads for boolean_t etc. in case of a custom BooleanType which is not -// an arithmetic type? -template < typename BasicJsonType, typename ArithmeticType, - enable_if_t < - std::is_arithmetic::value&& - !std::is_same::value&& - !std::is_same::value&& - !std::is_same::value&& - !std::is_same::value, - int > = 0 > -void from_json(const BasicJsonType& j, ArithmeticType& val) -{ - switch (static_cast(j)) - { - case value_t::number_unsigned: - { - val = static_cast(*j.template get_ptr()); - break; - } - case value_t::number_integer: - { - val = static_cast(*j.template get_ptr()); - break; - } - case value_t::number_float: - { - val = static_cast(*j.template get_ptr()); - break; - } - case value_t::boolean: - { - val = static_cast(*j.template get_ptr()); - break; - } - - default: - JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()))); - } -} - -template -void from_json(const BasicJsonType& j, std::pair& p) -{ - p = {j.at(0).template get(), j.at(1).template get()}; -} - -template -void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence /*unused*/) -{ - t = std::make_tuple(j.at(Idx).template get::type>()...); -} - -template -void from_json(const BasicJsonType& j, std::tuple& t) -{ - from_json_tuple_impl(j, t, index_sequence_for {}); -} - -template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator, - typename = enable_if_t < !std::is_constructible < - typename BasicJsonType::string_t, Key >::value >> -void from_json(const BasicJsonType& j, std::map& m) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_array())) - { - JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()))); - } - m.clear(); - for (const auto& p : j) - { - if (JSON_HEDLEY_UNLIKELY(!p.is_array())) - { - JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()))); - } - m.emplace(p.at(0).template get(), p.at(1).template get()); - } -} - -template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator, - typename = enable_if_t < !std::is_constructible < - typename BasicJsonType::string_t, Key >::value >> -void from_json(const BasicJsonType& j, std::unordered_map& m) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_array())) - { - JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()))); - } - m.clear(); - for (const auto& p : j) - { - if (JSON_HEDLEY_UNLIKELY(!p.is_array())) - { - JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()))); - } - m.emplace(p.at(0).template get(), p.at(1).template get()); - } -} - -struct from_json_fn -{ - template - auto operator()(const BasicJsonType& j, T& val) const - noexcept(noexcept(from_json(j, val))) - -> decltype(from_json(j, val), void()) - { - return from_json(j, val); - } -}; -} // namespace detail - -/// namespace to hold default `from_json` function -/// to see why this is required: -/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html -namespace -{ -constexpr const auto& from_json = detail::static_const::value; -} // namespace -} // namespace nlohmann - -// #include - - -#include // copy -#include // begin, end -#include // string -#include // tuple, get -#include // is_same, is_constructible, is_floating_point, is_enum, underlying_type -#include // move, forward, declval, pair -#include // valarray -#include // vector - -// #include - - -#include // size_t -#include // input_iterator_tag -#include // string, to_string -#include // tuple_size, get, tuple_element - -// #include - -// #include - - -namespace nlohmann -{ -namespace detail -{ -template -void int_to_string( string_type& target, std::size_t value ) -{ - // For ADL - using std::to_string; - target = to_string(value); -} -template class iteration_proxy_value -{ - public: - using difference_type = std::ptrdiff_t; - using value_type = iteration_proxy_value; - using pointer = value_type * ; - using reference = value_type & ; - using iterator_category = std::input_iterator_tag; - using string_type = typename std::remove_cv< typename std::remove_reference().key() ) >::type >::type; - - private: - /// the iterator - IteratorType anchor; - /// an index for arrays (used to create key names) - std::size_t array_index = 0; - /// last stringified array index - mutable std::size_t array_index_last = 0; - /// a string representation of the array index - mutable string_type array_index_str = "0"; - /// an empty string (to return a reference for primitive values) - const string_type empty_str = ""; - - public: - explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {} - - /// dereference operator (needed for range-based for) - iteration_proxy_value& operator*() - { - return *this; - } - - /// increment operator (needed for range-based for) - iteration_proxy_value& operator++() - { - ++anchor; - ++array_index; - - return *this; - } - - /// equality operator (needed for InputIterator) - bool operator==(const iteration_proxy_value& o) const - { - return anchor == o.anchor; - } - - /// inequality operator (needed for range-based for) - bool operator!=(const iteration_proxy_value& o) const - { - return anchor != o.anchor; - } - - /// return key of the iterator - const string_type& key() const - { - JSON_ASSERT(anchor.m_object != nullptr); - - switch (anchor.m_object->type()) - { - // use integer array index as key - case value_t::array: - { - if (array_index != array_index_last) - { - int_to_string( array_index_str, array_index ); - array_index_last = array_index; - } - return array_index_str; - } - - // use key from the object - case value_t::object: - return anchor.key(); - - // use an empty key for all primitive types - default: - return empty_str; - } - } - - /// return value of the iterator - typename IteratorType::reference value() const - { - return anchor.value(); - } -}; - -/// proxy class for the items() function -template class iteration_proxy -{ - private: - /// the container to iterate - typename IteratorType::reference container; - - public: - /// construct iteration proxy from a container - explicit iteration_proxy(typename IteratorType::reference cont) noexcept - : container(cont) {} - - /// return iterator begin (needed for range-based for) - iteration_proxy_value begin() noexcept - { - return iteration_proxy_value(container.begin()); - } - - /// return iterator end (needed for range-based for) - iteration_proxy_value end() noexcept - { - return iteration_proxy_value(container.end()); - } -}; -// Structured Bindings Support -// For further reference see https://blog.tartanllama.xyz/structured-bindings/ -// And see https://github.com/nlohmann/json/pull/1391 -template = 0> -auto get(const nlohmann::detail::iteration_proxy_value& i) -> decltype(i.key()) -{ - return i.key(); -} -// Structured Bindings Support -// For further reference see https://blog.tartanllama.xyz/structured-bindings/ -// And see https://github.com/nlohmann/json/pull/1391 -template = 0> -auto get(const nlohmann::detail::iteration_proxy_value& i) -> decltype(i.value()) -{ - return i.value(); -} -} // namespace detail -} // namespace nlohmann - -// The Addition to the STD Namespace is required to add -// Structured Bindings Support to the iteration_proxy_value class -// For further reference see https://blog.tartanllama.xyz/structured-bindings/ -// And see https://github.com/nlohmann/json/pull/1391 -namespace std -{ -#if defined(__clang__) - // Fix: https://github.com/nlohmann/json/issues/1401 - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wmismatched-tags" -#endif -template -class tuple_size<::nlohmann::detail::iteration_proxy_value> - : public std::integral_constant {}; - -template -class tuple_element> -{ - public: - using type = decltype( - get(std::declval < - ::nlohmann::detail::iteration_proxy_value> ())); -}; -#if defined(__clang__) - #pragma clang diagnostic pop -#endif -} // namespace std - -// #include - -// #include - -// #include - - -namespace nlohmann -{ -namespace detail -{ -////////////////// -// constructors // -////////////////// - -template struct external_constructor; - -template<> -struct external_constructor -{ - template - static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept - { - j.m_type = value_t::boolean; - j.m_value = b; - j.assert_invariant(); - } -}; - -template<> -struct external_constructor -{ - template - static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s) - { - j.m_type = value_t::string; - j.m_value = s; - j.assert_invariant(); - } - - template - static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s) - { - j.m_type = value_t::string; - j.m_value = std::move(s); - j.assert_invariant(); - } - - template < typename BasicJsonType, typename CompatibleStringType, - enable_if_t < !std::is_same::value, - int > = 0 > - static void construct(BasicJsonType& j, const CompatibleStringType& str) - { - j.m_type = value_t::string; - j.m_value.string = j.template create(str); - j.assert_invariant(); - } -}; - -template<> -struct external_constructor -{ - template - static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b) - { - j.m_type = value_t::binary; - typename BasicJsonType::binary_t value{b}; - j.m_value = value; - j.assert_invariant(); - } - - template - static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b) - { - j.m_type = value_t::binary; - typename BasicJsonType::binary_t value{std::move(b)}; - j.m_value = value; - j.assert_invariant(); - } -}; - -template<> -struct external_constructor -{ - template - static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept - { - j.m_type = value_t::number_float; - j.m_value = val; - j.assert_invariant(); - } -}; - -template<> -struct external_constructor -{ - template - static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept - { - j.m_type = value_t::number_unsigned; - j.m_value = val; - j.assert_invariant(); - } -}; - -template<> -struct external_constructor -{ - template - static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept - { - j.m_type = value_t::number_integer; - j.m_value = val; - j.assert_invariant(); - } -}; - -template<> -struct external_constructor -{ - template - static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr) - { - j.m_type = value_t::array; - j.m_value = arr; - j.assert_invariant(); - } - - template - static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr) - { - j.m_type = value_t::array; - j.m_value = std::move(arr); - j.assert_invariant(); - } - - template < typename BasicJsonType, typename CompatibleArrayType, - enable_if_t < !std::is_same::value, - int > = 0 > - static void construct(BasicJsonType& j, const CompatibleArrayType& arr) - { - using std::begin; - using std::end; - j.m_type = value_t::array; - j.m_value.array = j.template create(begin(arr), end(arr)); - j.assert_invariant(); - } - - template - static void construct(BasicJsonType& j, const std::vector& arr) - { - j.m_type = value_t::array; - j.m_value = value_t::array; - j.m_value.array->reserve(arr.size()); - for (const bool x : arr) - { - j.m_value.array->push_back(x); - } - j.assert_invariant(); - } - - template::value, int> = 0> - static void construct(BasicJsonType& j, const std::valarray& arr) - { - j.m_type = value_t::array; - j.m_value = value_t::array; - j.m_value.array->resize(arr.size()); - if (arr.size() > 0) - { - std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin()); - } - j.assert_invariant(); - } -}; - -template<> -struct external_constructor -{ - template - static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj) - { - j.m_type = value_t::object; - j.m_value = obj; - j.assert_invariant(); - } - - template - static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj) - { - j.m_type = value_t::object; - j.m_value = std::move(obj); - j.assert_invariant(); - } - - template < typename BasicJsonType, typename CompatibleObjectType, - enable_if_t < !std::is_same::value, int > = 0 > - static void construct(BasicJsonType& j, const CompatibleObjectType& obj) - { - using std::begin; - using std::end; - - j.m_type = value_t::object; - j.m_value.object = j.template create(begin(obj), end(obj)); - j.assert_invariant(); - } -}; - -///////////// -// to_json // -///////////// - -template::value, int> = 0> -void to_json(BasicJsonType& j, T b) noexcept -{ - external_constructor::construct(j, b); -} - -template::value, int> = 0> -void to_json(BasicJsonType& j, const CompatibleString& s) -{ - external_constructor::construct(j, s); -} - -template -void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s) -{ - external_constructor::construct(j, std::move(s)); -} - -template::value, int> = 0> -void to_json(BasicJsonType& j, FloatType val) noexcept -{ - external_constructor::construct(j, static_cast(val)); -} - -template::value, int> = 0> -void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept -{ - external_constructor::construct(j, static_cast(val)); -} - -template::value, int> = 0> -void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept -{ - external_constructor::construct(j, static_cast(val)); -} - -template::value, int> = 0> -void to_json(BasicJsonType& j, EnumType e) noexcept -{ - using underlying_type = typename std::underlying_type::type; - external_constructor::construct(j, static_cast(e)); -} - -template -void to_json(BasicJsonType& j, const std::vector& e) -{ - external_constructor::construct(j, e); -} - -template < typename BasicJsonType, typename CompatibleArrayType, - enable_if_t < is_compatible_array_type::value&& - !is_compatible_object_type::value&& - !is_compatible_string_type::value&& - !std::is_same::value&& - !is_basic_json::value, - int > = 0 > -void to_json(BasicJsonType& j, const CompatibleArrayType& arr) -{ - external_constructor::construct(j, arr); -} - -template -void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin) -{ - external_constructor::construct(j, bin); -} - -template::value, int> = 0> -void to_json(BasicJsonType& j, const std::valarray& arr) -{ - external_constructor::construct(j, std::move(arr)); -} - -template -void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr) -{ - external_constructor::construct(j, std::move(arr)); -} - -template < typename BasicJsonType, typename CompatibleObjectType, - enable_if_t < is_compatible_object_type::value&& !is_basic_json::value, int > = 0 > -void to_json(BasicJsonType& j, const CompatibleObjectType& obj) -{ - external_constructor::construct(j, obj); -} - -template -void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj) -{ - external_constructor::construct(j, std::move(obj)); -} - -template < - typename BasicJsonType, typename T, std::size_t N, - enable_if_t < !std::is_constructible::value, - int > = 0 > -void to_json(BasicJsonType& j, const T(&arr)[N]) -{ - external_constructor::construct(j, arr); -} - -template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible::value&& std::is_constructible::value, int > = 0 > -void to_json(BasicJsonType& j, const std::pair& p) -{ - j = { p.first, p.second }; -} - -// for https://github.com/nlohmann/json/pull/1134 -template>::value, int> = 0> -void to_json(BasicJsonType& j, const T& b) -{ - j = { {b.key(), b.value()} }; -} - -template -void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence /*unused*/) -{ - j = { std::get(t)... }; -} - -template::value, int > = 0> -void to_json(BasicJsonType& j, const T& t) -{ - to_json_tuple_impl(j, t, make_index_sequence::value> {}); -} - -struct to_json_fn -{ - template - auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward(val)))) - -> decltype(to_json(j, std::forward(val)), void()) - { - return to_json(j, std::forward(val)); - } -}; -} // namespace detail - -/// namespace to hold default `to_json` function -namespace -{ -constexpr const auto& to_json = detail::static_const::value; -} // namespace -} // namespace nlohmann - - -namespace nlohmann -{ - -template -struct adl_serializer -{ - /*! - @brief convert a JSON value to any value type - - This function is usually called by the `get()` function of the - @ref basic_json class (either explicit or via conversion operators). - - @param[in] j JSON value to read from - @param[in,out] val value to write to - */ - template - static auto from_json(BasicJsonType&& j, ValueType& val) noexcept( - noexcept(::nlohmann::from_json(std::forward(j), val))) - -> decltype(::nlohmann::from_json(std::forward(j), val), void()) - { - ::nlohmann::from_json(std::forward(j), val); - } - - /*! - @brief convert any value type to a JSON value - - This function is usually called by the constructors of the @ref basic_json - class. - - @param[in,out] j JSON value to write to - @param[in] val value to read from - */ - template - static auto to_json(BasicJsonType& j, ValueType&& val) noexcept( - noexcept(::nlohmann::to_json(j, std::forward(val)))) - -> decltype(::nlohmann::to_json(j, std::forward(val)), void()) - { - ::nlohmann::to_json(j, std::forward(val)); - } -}; - -} // namespace nlohmann - -// #include - - -#include // uint8_t -#include // tie -#include // move - -namespace nlohmann -{ - -/*! -@brief an internal type for a backed binary type - -This type extends the template parameter @a BinaryType provided to `basic_json` -with a subtype used by BSON and MessagePack. This type exists so that the user -does not have to specify a type themselves with a specific naming scheme in -order to override the binary type. - -@tparam BinaryType container to store bytes (`std::vector` by - default) - -@since version 3.8.0 -*/ -template -class byte_container_with_subtype : public BinaryType -{ - public: - /// the type of the underlying container - using container_type = BinaryType; - - byte_container_with_subtype() noexcept(noexcept(container_type())) - : container_type() - {} - - byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b))) - : container_type(b) - {} - - byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b)))) - : container_type(std::move(b)) - {} - - byte_container_with_subtype(const container_type& b, std::uint8_t subtype) noexcept(noexcept(container_type(b))) - : container_type(b) - , m_subtype(subtype) - , m_has_subtype(true) - {} - - byte_container_with_subtype(container_type&& b, std::uint8_t subtype) noexcept(noexcept(container_type(std::move(b)))) - : container_type(std::move(b)) - , m_subtype(subtype) - , m_has_subtype(true) - {} - - bool operator==(const byte_container_with_subtype& rhs) const - { - return std::tie(static_cast(*this), m_subtype, m_has_subtype) == - std::tie(static_cast(rhs), rhs.m_subtype, rhs.m_has_subtype); - } - - bool operator!=(const byte_container_with_subtype& rhs) const - { - return !(rhs == *this); - } - - /*! - @brief sets the binary subtype - - Sets the binary subtype of the value, also flags a binary JSON value as - having a subtype, which has implications for serialization. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @sa @ref subtype() -- return the binary subtype - @sa @ref clear_subtype() -- clears the binary subtype - @sa @ref has_subtype() -- returns whether or not the binary value has a - subtype - - @since version 3.8.0 - */ - void set_subtype(std::uint8_t subtype) noexcept - { - m_subtype = subtype; - m_has_subtype = true; - } - - /*! - @brief return the binary subtype - - Returns the numerical subtype of the value if it has a subtype. If it does - not have a subtype, this function will return size_t(-1) as a sentinel - value. - - @return the numerical subtype of the binary value - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @sa @ref set_subtype() -- sets the binary subtype - @sa @ref clear_subtype() -- clears the binary subtype - @sa @ref has_subtype() -- returns whether or not the binary value has a - subtype - - @since version 3.8.0 - */ - constexpr std::uint8_t subtype() const noexcept - { - return m_subtype; - } - - /*! - @brief return whether the value has a subtype - - @return whether the value has a subtype - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @sa @ref subtype() -- return the binary subtype - @sa @ref set_subtype() -- sets the binary subtype - @sa @ref clear_subtype() -- clears the binary subtype - - @since version 3.8.0 - */ - constexpr bool has_subtype() const noexcept - { - return m_has_subtype; - } - - /*! - @brief clears the binary subtype - - Clears the binary subtype and flags the value as not having a subtype, which - has implications for serialization; for instance MessagePack will prefer the - bin family over the ext family. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @sa @ref subtype() -- return the binary subtype - @sa @ref set_subtype() -- sets the binary subtype - @sa @ref has_subtype() -- returns whether or not the binary value has a - subtype - - @since version 3.8.0 - */ - void clear_subtype() noexcept - { - m_subtype = 0; - m_has_subtype = false; - } - - private: - std::uint8_t m_subtype = 0; - bool m_has_subtype = false; -}; - -} // namespace nlohmann - -// #include - -// #include - -// #include - -// #include - - -#include // size_t, uint8_t -#include // hash - -namespace nlohmann -{ -namespace detail -{ - -// boost::hash_combine -inline std::size_t combine(std::size_t seed, std::size_t h) noexcept -{ - seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U); - return seed; -} - -/*! -@brief hash a JSON value - -The hash function tries to rely on std::hash where possible. Furthermore, the -type of the JSON value is taken into account to have different hash values for -null, 0, 0U, and false, etc. - -@tparam BasicJsonType basic_json specialization -@param j JSON value to hash -@return hash value of j -*/ -template -std::size_t hash(const BasicJsonType& j) -{ - using string_t = typename BasicJsonType::string_t; - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using number_float_t = typename BasicJsonType::number_float_t; - - const auto type = static_cast(j.type()); - switch (j.type()) - { - case BasicJsonType::value_t::null: - case BasicJsonType::value_t::discarded: - { - return combine(type, 0); - } - - case BasicJsonType::value_t::object: - { - auto seed = combine(type, j.size()); - for (const auto& element : j.items()) - { - const auto h = std::hash {}(element.key()); - seed = combine(seed, h); - seed = combine(seed, hash(element.value())); - } - return seed; - } - - case BasicJsonType::value_t::array: - { - auto seed = combine(type, j.size()); - for (const auto& element : j) - { - seed = combine(seed, hash(element)); - } - return seed; - } - - case BasicJsonType::value_t::string: - { - const auto h = std::hash {}(j.template get_ref()); - return combine(type, h); - } - - case BasicJsonType::value_t::boolean: - { - const auto h = std::hash {}(j.template get()); - return combine(type, h); - } - - case BasicJsonType::value_t::number_integer: - { - const auto h = std::hash {}(j.template get()); - return combine(type, h); - } - - case nlohmann::detail::value_t::number_unsigned: - { - const auto h = std::hash {}(j.template get()); - return combine(type, h); - } - - case nlohmann::detail::value_t::number_float: - { - const auto h = std::hash {}(j.template get()); - return combine(type, h); - } - - case nlohmann::detail::value_t::binary: - { - auto seed = combine(type, j.get_binary().size()); - const auto h = std::hash {}(j.get_binary().has_subtype()); - seed = combine(seed, h); - seed = combine(seed, j.get_binary().subtype()); - for (const auto byte : j.get_binary()) - { - seed = combine(seed, std::hash {}(byte)); - } - return seed; - } - - default: // LCOV_EXCL_LINE - JSON_ASSERT(false); // LCOV_EXCL_LINE - } -} - -} // namespace detail -} // namespace nlohmann - -// #include - - -#include // generate_n -#include // array -#include // ldexp -#include // size_t -#include // uint8_t, uint16_t, uint32_t, uint64_t -#include // snprintf -#include // memcpy -#include // back_inserter -#include // numeric_limits -#include // char_traits, string -#include // make_pair, move - -// #include - -// #include - - -#include // array -#include // size_t -#include //FILE * -#include // strlen -#include // istream -#include // begin, end, iterator_traits, random_access_iterator_tag, distance, next -#include // shared_ptr, make_shared, addressof -#include // accumulate -#include // string, char_traits -#include // enable_if, is_base_of, is_pointer, is_integral, remove_pointer -#include // pair, declval - -// #include - -// #include - - -namespace nlohmann -{ -namespace detail -{ -/// the supported input formats -enum class input_format_t { json, cbor, msgpack, ubjson, bson }; - -//////////////////// -// input adapters // -//////////////////// - -/*! -Input adapter for stdio file access. This adapter read only 1 byte and do not use any - buffer. This adapter is a very low level adapter. -*/ -class file_input_adapter -{ - public: - using char_type = char; - - JSON_HEDLEY_NON_NULL(2) - explicit file_input_adapter(std::FILE* f) noexcept - : m_file(f) - {} - - // make class move-only - file_input_adapter(const file_input_adapter&) = delete; - file_input_adapter(file_input_adapter&&) = default; - file_input_adapter& operator=(const file_input_adapter&) = delete; - file_input_adapter& operator=(file_input_adapter&&) = delete; - - std::char_traits::int_type get_character() noexcept - { - return std::fgetc(m_file); - } - - private: - /// the file pointer to read from - std::FILE* m_file; -}; - - -/*! -Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at -beginning of input. Does not support changing the underlying std::streambuf -in mid-input. Maintains underlying std::istream and std::streambuf to support -subsequent use of standard std::istream operations to process any input -characters following those used in parsing the JSON input. Clears the -std::istream flags; any input errors (e.g., EOF) will be detected by the first -subsequent call for input from the std::istream. -*/ -class input_stream_adapter -{ - public: - using char_type = char; - - ~input_stream_adapter() - { - // clear stream flags; we use underlying streambuf I/O, do not - // maintain ifstream flags, except eof - if (is != nullptr) - { - is->clear(is->rdstate() & std::ios::eofbit); - } - } - - explicit input_stream_adapter(std::istream& i) - : is(&i), sb(i.rdbuf()) - {} - - // delete because of pointer members - input_stream_adapter(const input_stream_adapter&) = delete; - input_stream_adapter& operator=(input_stream_adapter&) = delete; - input_stream_adapter& operator=(input_stream_adapter&& rhs) = delete; - - input_stream_adapter(input_stream_adapter&& rhs) noexcept : is(rhs.is), sb(rhs.sb) - { - rhs.is = nullptr; - rhs.sb = nullptr; - } - - // std::istream/std::streambuf use std::char_traits::to_int_type, to - // ensure that std::char_traits::eof() and the character 0xFF do not - // end up as the same value, eg. 0xFFFFFFFF. - std::char_traits::int_type get_character() - { - auto res = sb->sbumpc(); - // set eof manually, as we don't use the istream interface. - if (JSON_HEDLEY_UNLIKELY(res == EOF)) - { - is->clear(is->rdstate() | std::ios::eofbit); - } - return res; - } - - private: - /// the associated input stream - std::istream* is = nullptr; - std::streambuf* sb = nullptr; -}; - -// General-purpose iterator-based adapter. It might not be as fast as -// theoretically possible for some containers, but it is extremely versatile. -template -class iterator_input_adapter -{ - public: - using char_type = typename std::iterator_traits::value_type; - - iterator_input_adapter(IteratorType first, IteratorType last) - : current(std::move(first)), end(std::move(last)) {} - - typename std::char_traits::int_type get_character() - { - if (JSON_HEDLEY_LIKELY(current != end)) - { - auto result = std::char_traits::to_int_type(*current); - std::advance(current, 1); - return result; - } - else - { - return std::char_traits::eof(); - } - } - - private: - IteratorType current; - IteratorType end; - - template - friend struct wide_string_input_helper; - - bool empty() const - { - return current == end; - } - -}; - - -template -struct wide_string_input_helper; - -template -struct wide_string_input_helper -{ - // UTF-32 - static void fill_buffer(BaseInputAdapter& input, - std::array::int_type, 4>& utf8_bytes, - size_t& utf8_bytes_index, - size_t& utf8_bytes_filled) - { - utf8_bytes_index = 0; - - if (JSON_HEDLEY_UNLIKELY(input.empty())) - { - utf8_bytes[0] = std::char_traits::eof(); - utf8_bytes_filled = 1; - } - else - { - // get the current character - const auto wc = input.get_character(); - - // UTF-32 to UTF-8 encoding - if (wc < 0x80) - { - utf8_bytes[0] = static_cast::int_type>(wc); - utf8_bytes_filled = 1; - } - else if (wc <= 0x7FF) - { - utf8_bytes[0] = static_cast::int_type>(0xC0u | ((static_cast(wc) >> 6u) & 0x1Fu)); - utf8_bytes[1] = static_cast::int_type>(0x80u | (static_cast(wc) & 0x3Fu)); - utf8_bytes_filled = 2; - } - else if (wc <= 0xFFFF) - { - utf8_bytes[0] = static_cast::int_type>(0xE0u | ((static_cast(wc) >> 12u) & 0x0Fu)); - utf8_bytes[1] = static_cast::int_type>(0x80u | ((static_cast(wc) >> 6u) & 0x3Fu)); - utf8_bytes[2] = static_cast::int_type>(0x80u | (static_cast(wc) & 0x3Fu)); - utf8_bytes_filled = 3; - } - else if (wc <= 0x10FFFF) - { - utf8_bytes[0] = static_cast::int_type>(0xF0u | ((static_cast(wc) >> 18u) & 0x07u)); - utf8_bytes[1] = static_cast::int_type>(0x80u | ((static_cast(wc) >> 12u) & 0x3Fu)); - utf8_bytes[2] = static_cast::int_type>(0x80u | ((static_cast(wc) >> 6u) & 0x3Fu)); - utf8_bytes[3] = static_cast::int_type>(0x80u | (static_cast(wc) & 0x3Fu)); - utf8_bytes_filled = 4; - } - else - { - // unknown character - utf8_bytes[0] = static_cast::int_type>(wc); - utf8_bytes_filled = 1; - } - } - } -}; - -template -struct wide_string_input_helper -{ - // UTF-16 - static void fill_buffer(BaseInputAdapter& input, - std::array::int_type, 4>& utf8_bytes, - size_t& utf8_bytes_index, - size_t& utf8_bytes_filled) - { - utf8_bytes_index = 0; - - if (JSON_HEDLEY_UNLIKELY(input.empty())) - { - utf8_bytes[0] = std::char_traits::eof(); - utf8_bytes_filled = 1; - } - else - { - // get the current character - const auto wc = input.get_character(); - - // UTF-16 to UTF-8 encoding - if (wc < 0x80) - { - utf8_bytes[0] = static_cast::int_type>(wc); - utf8_bytes_filled = 1; - } - else if (wc <= 0x7FF) - { - utf8_bytes[0] = static_cast::int_type>(0xC0u | ((static_cast(wc) >> 6u))); - utf8_bytes[1] = static_cast::int_type>(0x80u | (static_cast(wc) & 0x3Fu)); - utf8_bytes_filled = 2; - } - else if (0xD800 > wc || wc >= 0xE000) - { - utf8_bytes[0] = static_cast::int_type>(0xE0u | ((static_cast(wc) >> 12u))); - utf8_bytes[1] = static_cast::int_type>(0x80u | ((static_cast(wc) >> 6u) & 0x3Fu)); - utf8_bytes[2] = static_cast::int_type>(0x80u | (static_cast(wc) & 0x3Fu)); - utf8_bytes_filled = 3; - } - else - { - if (JSON_HEDLEY_UNLIKELY(!input.empty())) - { - const auto wc2 = static_cast(input.get_character()); - const auto charcode = 0x10000u + (((static_cast(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu)); - utf8_bytes[0] = static_cast::int_type>(0xF0u | (charcode >> 18u)); - utf8_bytes[1] = static_cast::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu)); - utf8_bytes[2] = static_cast::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu)); - utf8_bytes[3] = static_cast::int_type>(0x80u | (charcode & 0x3Fu)); - utf8_bytes_filled = 4; - } - else - { - utf8_bytes[0] = static_cast::int_type>(wc); - utf8_bytes_filled = 1; - } - } - } - } -}; - -// Wraps another input apdater to convert wide character types into individual bytes. -template -class wide_string_input_adapter -{ - public: - using char_type = char; - - wide_string_input_adapter(BaseInputAdapter base) - : base_adapter(base) {} - - typename std::char_traits::int_type get_character() noexcept - { - // check if buffer needs to be filled - if (utf8_bytes_index == utf8_bytes_filled) - { - fill_buffer(); - - JSON_ASSERT(utf8_bytes_filled > 0); - JSON_ASSERT(utf8_bytes_index == 0); - } - - // use buffer - JSON_ASSERT(utf8_bytes_filled > 0); - JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled); - return utf8_bytes[utf8_bytes_index++]; - } - - private: - BaseInputAdapter base_adapter; - - template - void fill_buffer() - { - wide_string_input_helper::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled); - } - - /// a buffer for UTF-8 bytes - std::array::int_type, 4> utf8_bytes = {{0, 0, 0, 0}}; - - /// index to the utf8_codes array for the next valid byte - std::size_t utf8_bytes_index = 0; - /// number of valid bytes in the utf8_codes array - std::size_t utf8_bytes_filled = 0; -}; - - -template -struct iterator_input_adapter_factory -{ - using iterator_type = IteratorType; - using char_type = typename std::iterator_traits::value_type; - using adapter_type = iterator_input_adapter; - - static adapter_type create(IteratorType first, IteratorType last) - { - return adapter_type(std::move(first), std::move(last)); - } -}; - -template -struct is_iterator_of_multibyte -{ - using value_type = typename std::iterator_traits::value_type; - enum - { - value = sizeof(value_type) > 1 - }; -}; - -template -struct iterator_input_adapter_factory::value>> -{ - using iterator_type = IteratorType; - using char_type = typename std::iterator_traits::value_type; - using base_adapter_type = iterator_input_adapter; - using adapter_type = wide_string_input_adapter; - - static adapter_type create(IteratorType first, IteratorType last) - { - return adapter_type(base_adapter_type(std::move(first), std::move(last))); - } -}; - -// General purpose iterator-based input -template -typename iterator_input_adapter_factory::adapter_type input_adapter(IteratorType first, IteratorType last) -{ - using factory_type = iterator_input_adapter_factory; - return factory_type::create(first, last); -} - -// Convenience shorthand from container to iterator -template -auto input_adapter(const ContainerType& container) -> decltype(input_adapter(begin(container), end(container))) -{ - // Enable ADL - using std::begin; - using std::end; - - return input_adapter(begin(container), end(container)); -} - -// Special cases with fast paths -inline file_input_adapter input_adapter(std::FILE* file) -{ - return file_input_adapter(file); -} - -inline input_stream_adapter input_adapter(std::istream& stream) -{ - return input_stream_adapter(stream); -} - -inline input_stream_adapter input_adapter(std::istream&& stream) -{ - return input_stream_adapter(stream); -} - -using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval(), std::declval())); - -// Null-delimited strings, and the like. -template < typename CharT, - typename std::enable_if < - std::is_pointer::value&& - !std::is_array::value&& - std::is_integral::type>::value&& - sizeof(typename std::remove_pointer::type) == 1, - int >::type = 0 > -contiguous_bytes_input_adapter input_adapter(CharT b) -{ - auto length = std::strlen(reinterpret_cast(b)); - const auto* ptr = reinterpret_cast(b); - return input_adapter(ptr, ptr + length); -} - -template -auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) -{ - return input_adapter(array, array + N); -} - -// This class only handles inputs of input_buffer_adapter type. -// It's required so that expressions like {ptr, len} can be implicitely casted -// to the correct adapter. -class span_input_adapter -{ - public: - template < typename CharT, - typename std::enable_if < - std::is_pointer::value&& - std::is_integral::type>::value&& - sizeof(typename std::remove_pointer::type) == 1, - int >::type = 0 > - span_input_adapter(CharT b, std::size_t l) - : ia(reinterpret_cast(b), reinterpret_cast(b) + l) {} - - template::iterator_category, std::random_access_iterator_tag>::value, - int>::type = 0> - span_input_adapter(IteratorType first, IteratorType last) - : ia(input_adapter(first, last)) {} - - contiguous_bytes_input_adapter&& get() - { - return std::move(ia); - } - - private: - contiguous_bytes_input_adapter ia; -}; -} // namespace detail -} // namespace nlohmann - -// #include - - -#include -#include // string -#include // move -#include // vector - -// #include - -// #include - - -namespace nlohmann -{ - -/*! -@brief SAX interface - -This class describes the SAX interface used by @ref nlohmann::json::sax_parse. -Each function is called in different situations while the input is parsed. The -boolean return value informs the parser whether to continue processing the -input. -*/ -template -struct json_sax -{ - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using number_float_t = typename BasicJsonType::number_float_t; - using string_t = typename BasicJsonType::string_t; - using binary_t = typename BasicJsonType::binary_t; - - /*! - @brief a null value was read - @return whether parsing should proceed - */ - virtual bool null() = 0; - - /*! - @brief a boolean value was read - @param[in] val boolean value - @return whether parsing should proceed - */ - virtual bool boolean(bool val) = 0; - - /*! - @brief an integer number was read - @param[in] val integer value - @return whether parsing should proceed - */ - virtual bool number_integer(number_integer_t val) = 0; - - /*! - @brief an unsigned integer number was read - @param[in] val unsigned integer value - @return whether parsing should proceed - */ - virtual bool number_unsigned(number_unsigned_t val) = 0; - - /*! - @brief an floating-point number was read - @param[in] val floating-point value - @param[in] s raw token value - @return whether parsing should proceed - */ - virtual bool number_float(number_float_t val, const string_t& s) = 0; - - /*! - @brief a string was read - @param[in] val string value - @return whether parsing should proceed - @note It is safe to move the passed string. - */ - virtual bool string(string_t& val) = 0; - - /*! - @brief a binary string was read - @param[in] val binary value - @return whether parsing should proceed - @note It is safe to move the passed binary. - */ - virtual bool binary(binary_t& val) = 0; - - /*! - @brief the beginning of an object was read - @param[in] elements number of object elements or -1 if unknown - @return whether parsing should proceed - @note binary formats may report the number of elements - */ - virtual bool start_object(std::size_t elements) = 0; - - /*! - @brief an object key was read - @param[in] val object key - @return whether parsing should proceed - @note It is safe to move the passed string. - */ - virtual bool key(string_t& val) = 0; - - /*! - @brief the end of an object was read - @return whether parsing should proceed - */ - virtual bool end_object() = 0; - - /*! - @brief the beginning of an array was read - @param[in] elements number of array elements or -1 if unknown - @return whether parsing should proceed - @note binary formats may report the number of elements - */ - virtual bool start_array(std::size_t elements) = 0; - - /*! - @brief the end of an array was read - @return whether parsing should proceed - */ - virtual bool end_array() = 0; - - /*! - @brief a parse error occurred - @param[in] position the position in the input where the error occurs - @param[in] last_token the last read token - @param[in] ex an exception object describing the error - @return whether parsing should proceed (must return false) - */ - virtual bool parse_error(std::size_t position, - const std::string& last_token, - const detail::exception& ex) = 0; - - virtual ~json_sax() = default; -}; - - -namespace detail -{ -/*! -@brief SAX implementation to create a JSON value from SAX events - -This class implements the @ref json_sax interface and processes the SAX events -to create a JSON value which makes it basically a DOM parser. The structure or -hierarchy of the JSON value is managed by the stack `ref_stack` which contains -a pointer to the respective array or object for each recursion depth. - -After successful parsing, the value that is passed by reference to the -constructor contains the parsed value. - -@tparam BasicJsonType the JSON type -*/ -template -class json_sax_dom_parser -{ - public: - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using number_float_t = typename BasicJsonType::number_float_t; - using string_t = typename BasicJsonType::string_t; - using binary_t = typename BasicJsonType::binary_t; - - /*! - @param[in, out] r reference to a JSON value that is manipulated while - parsing - @param[in] allow_exceptions_ whether parse errors yield exceptions - */ - explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true) - : root(r), allow_exceptions(allow_exceptions_) - {} - - // make class move-only - json_sax_dom_parser(const json_sax_dom_parser&) = delete; - json_sax_dom_parser(json_sax_dom_parser&&) = default; - json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete; - json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; - ~json_sax_dom_parser() = default; - - bool null() - { - handle_value(nullptr); - return true; - } - - bool boolean(bool val) - { - handle_value(val); - return true; - } - - bool number_integer(number_integer_t val) - { - handle_value(val); - return true; - } - - bool number_unsigned(number_unsigned_t val) - { - handle_value(val); - return true; - } - - bool number_float(number_float_t val, const string_t& /*unused*/) - { - handle_value(val); - return true; - } - - bool string(string_t& val) - { - handle_value(val); - return true; - } - - bool binary(binary_t& val) - { - handle_value(std::move(val)); - return true; - } - - bool start_object(std::size_t len) - { - ref_stack.push_back(handle_value(BasicJsonType::value_t::object)); - - if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size())) - { - JSON_THROW(out_of_range::create(408, - "excessive object size: " + std::to_string(len))); - } - - return true; - } - - bool key(string_t& val) - { - // add null at given key and store the reference for later - object_element = &(ref_stack.back()->m_value.object->operator[](val)); - return true; - } - - bool end_object() - { - ref_stack.pop_back(); - return true; - } - - bool start_array(std::size_t len) - { - ref_stack.push_back(handle_value(BasicJsonType::value_t::array)); - - if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size())) - { - JSON_THROW(out_of_range::create(408, - "excessive array size: " + std::to_string(len))); - } - - return true; - } - - bool end_array() - { - ref_stack.pop_back(); - return true; - } - - template - bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, - const Exception& ex) - { - errored = true; - static_cast(ex); - if (allow_exceptions) - { - JSON_THROW(ex); - } - return false; - } - - constexpr bool is_errored() const - { - return errored; - } - - private: - /*! - @invariant If the ref stack is empty, then the passed value will be the new - root. - @invariant If the ref stack contains a value, then it is an array or an - object to which we can add elements - */ - template - JSON_HEDLEY_RETURNS_NON_NULL - BasicJsonType* handle_value(Value&& v) - { - if (ref_stack.empty()) - { - root = BasicJsonType(std::forward(v)); - return &root; - } - - JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object()); - - if (ref_stack.back()->is_array()) - { - ref_stack.back()->m_value.array->emplace_back(std::forward(v)); - return &(ref_stack.back()->m_value.array->back()); - } - - JSON_ASSERT(ref_stack.back()->is_object()); - JSON_ASSERT(object_element); - *object_element = BasicJsonType(std::forward(v)); - return object_element; - } - - /// the parsed JSON value - BasicJsonType& root; - /// stack to model hierarchy of values - std::vector ref_stack {}; - /// helper to hold the reference for the next object element - BasicJsonType* object_element = nullptr; - /// whether a syntax error occurred - bool errored = false; - /// whether to throw exceptions in case of errors - const bool allow_exceptions = true; -}; - -template -class json_sax_dom_callback_parser -{ - public: - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using number_float_t = typename BasicJsonType::number_float_t; - using string_t = typename BasicJsonType::string_t; - using binary_t = typename BasicJsonType::binary_t; - using parser_callback_t = typename BasicJsonType::parser_callback_t; - using parse_event_t = typename BasicJsonType::parse_event_t; - - json_sax_dom_callback_parser(BasicJsonType& r, - const parser_callback_t cb, - const bool allow_exceptions_ = true) - : root(r), callback(cb), allow_exceptions(allow_exceptions_) - { - keep_stack.push_back(true); - } - - // make class move-only - json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete; - json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; - json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete; - json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; - ~json_sax_dom_callback_parser() = default; - - bool null() - { - handle_value(nullptr); - return true; - } - - bool boolean(bool val) - { - handle_value(val); - return true; - } - - bool number_integer(number_integer_t val) - { - handle_value(val); - return true; - } - - bool number_unsigned(number_unsigned_t val) - { - handle_value(val); - return true; - } - - bool number_float(number_float_t val, const string_t& /*unused*/) - { - handle_value(val); - return true; - } - - bool string(string_t& val) - { - handle_value(val); - return true; - } - - bool binary(binary_t& val) - { - handle_value(std::move(val)); - return true; - } - - bool start_object(std::size_t len) - { - // check callback for object start - const bool keep = callback(static_cast(ref_stack.size()), parse_event_t::object_start, discarded); - keep_stack.push_back(keep); - - auto val = handle_value(BasicJsonType::value_t::object, true); - ref_stack.push_back(val.second); - - // check object limit - if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size())) - { - JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len))); - } - - return true; - } - - bool key(string_t& val) - { - BasicJsonType k = BasicJsonType(val); - - // check callback for key - const bool keep = callback(static_cast(ref_stack.size()), parse_event_t::key, k); - key_keep_stack.push_back(keep); - - // add discarded value at given key and store the reference for later - if (keep && ref_stack.back()) - { - object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded); - } - - return true; - } - - bool end_object() - { - if (ref_stack.back() && !callback(static_cast(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back())) - { - // discard object - *ref_stack.back() = discarded; - } - - JSON_ASSERT(!ref_stack.empty()); - JSON_ASSERT(!keep_stack.empty()); - ref_stack.pop_back(); - keep_stack.pop_back(); - - if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured()) - { - // remove discarded value - for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it) - { - if (it->is_discarded()) - { - ref_stack.back()->erase(it); - break; - } - } - } - - return true; - } - - bool start_array(std::size_t len) - { - const bool keep = callback(static_cast(ref_stack.size()), parse_event_t::array_start, discarded); - keep_stack.push_back(keep); - - auto val = handle_value(BasicJsonType::value_t::array, true); - ref_stack.push_back(val.second); - - // check array limit - if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size())) - { - JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len))); - } - - return true; - } - - bool end_array() - { - bool keep = true; - - if (ref_stack.back()) - { - keep = callback(static_cast(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back()); - if (!keep) - { - // discard array - *ref_stack.back() = discarded; - } - } - - JSON_ASSERT(!ref_stack.empty()); - JSON_ASSERT(!keep_stack.empty()); - ref_stack.pop_back(); - keep_stack.pop_back(); - - // remove discarded value - if (!keep && !ref_stack.empty() && ref_stack.back()->is_array()) - { - ref_stack.back()->m_value.array->pop_back(); - } - - return true; - } - - template - bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, - const Exception& ex) - { - errored = true; - static_cast(ex); - if (allow_exceptions) - { - JSON_THROW(ex); - } - return false; - } - - constexpr bool is_errored() const - { - return errored; - } - - private: - /*! - @param[in] v value to add to the JSON value we build during parsing - @param[in] skip_callback whether we should skip calling the callback - function; this is required after start_array() and - start_object() SAX events, because otherwise we would call the - callback function with an empty array or object, respectively. - - @invariant If the ref stack is empty, then the passed value will be the new - root. - @invariant If the ref stack contains a value, then it is an array or an - object to which we can add elements - - @return pair of boolean (whether value should be kept) and pointer (to the - passed value in the ref_stack hierarchy; nullptr if not kept) - */ - template - std::pair handle_value(Value&& v, const bool skip_callback = false) - { - JSON_ASSERT(!keep_stack.empty()); - - // do not handle this value if we know it would be added to a discarded - // container - if (!keep_stack.back()) - { - return {false, nullptr}; - } - - // create value - auto value = BasicJsonType(std::forward(v)); - - // check callback - const bool keep = skip_callback || callback(static_cast(ref_stack.size()), parse_event_t::value, value); - - // do not handle this value if we just learnt it shall be discarded - if (!keep) - { - return {false, nullptr}; - } - - if (ref_stack.empty()) - { - root = std::move(value); - return {true, &root}; - } - - // skip this value if we already decided to skip the parent - // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360) - if (!ref_stack.back()) - { - return {false, nullptr}; - } - - // we now only expect arrays and objects - JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object()); - - // array - if (ref_stack.back()->is_array()) - { - ref_stack.back()->m_value.array->push_back(std::move(value)); - return {true, &(ref_stack.back()->m_value.array->back())}; - } - - // object - JSON_ASSERT(ref_stack.back()->is_object()); - // check if we should store an element for the current key - JSON_ASSERT(!key_keep_stack.empty()); - const bool store_element = key_keep_stack.back(); - key_keep_stack.pop_back(); - - if (!store_element) - { - return {false, nullptr}; - } - - JSON_ASSERT(object_element); - *object_element = std::move(value); - return {true, object_element}; - } - - /// the parsed JSON value - BasicJsonType& root; - /// stack to model hierarchy of values - std::vector ref_stack {}; - /// stack to manage which values to keep - std::vector keep_stack {}; - /// stack to manage which object keys to keep - std::vector key_keep_stack {}; - /// helper to hold the reference for the next object element - BasicJsonType* object_element = nullptr; - /// whether a syntax error occurred - bool errored = false; - /// callback function - const parser_callback_t callback = nullptr; - /// whether to throw exceptions in case of errors - const bool allow_exceptions = true; - /// a discarded value for the callback - BasicJsonType discarded = BasicJsonType::value_t::discarded; -}; - -template -class json_sax_acceptor -{ - public: - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using number_float_t = typename BasicJsonType::number_float_t; - using string_t = typename BasicJsonType::string_t; - using binary_t = typename BasicJsonType::binary_t; - - bool null() - { - return true; - } - - bool boolean(bool /*unused*/) - { - return true; - } - - bool number_integer(number_integer_t /*unused*/) - { - return true; - } - - bool number_unsigned(number_unsigned_t /*unused*/) - { - return true; - } - - bool number_float(number_float_t /*unused*/, const string_t& /*unused*/) - { - return true; - } - - bool string(string_t& /*unused*/) - { - return true; - } - - bool binary(binary_t& /*unused*/) - { - return true; - } - - bool start_object(std::size_t /*unused*/ = std::size_t(-1)) - { - return true; - } - - bool key(string_t& /*unused*/) - { - return true; - } - - bool end_object() - { - return true; - } - - bool start_array(std::size_t /*unused*/ = std::size_t(-1)) - { - return true; - } - - bool end_array() - { - return true; - } - - bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/) - { - return false; - } -}; -} // namespace detail - -} // namespace nlohmann - -// #include - - -#include // array -#include // localeconv -#include // size_t -#include // snprintf -#include // strtof, strtod, strtold, strtoll, strtoull -#include // initializer_list -#include // char_traits, string -#include // move -#include // vector - -// #include - -// #include - -// #include - - -namespace nlohmann -{ -namespace detail -{ -/////////// -// lexer // -/////////// - -template -class lexer_base -{ - public: - /// token types for the parser - enum class token_type - { - uninitialized, ///< indicating the scanner is uninitialized - literal_true, ///< the `true` literal - literal_false, ///< the `false` literal - literal_null, ///< the `null` literal - value_string, ///< a string -- use get_string() for actual value - value_unsigned, ///< an unsigned integer -- use get_number_unsigned() for actual value - value_integer, ///< a signed integer -- use get_number_integer() for actual value - value_float, ///< an floating point number -- use get_number_float() for actual value - begin_array, ///< the character for array begin `[` - begin_object, ///< the character for object begin `{` - end_array, ///< the character for array end `]` - end_object, ///< the character for object end `}` - name_separator, ///< the name separator `:` - value_separator, ///< the value separator `,` - parse_error, ///< indicating a parse error - end_of_input, ///< indicating the end of the input buffer - literal_or_value ///< a literal or the begin of a value (only for diagnostics) - }; - - /// return name of values of type token_type (only used for errors) - JSON_HEDLEY_RETURNS_NON_NULL - JSON_HEDLEY_CONST - static const char* token_type_name(const token_type t) noexcept - { - switch (t) - { - case token_type::uninitialized: - return ""; - case token_type::literal_true: - return "true literal"; - case token_type::literal_false: - return "false literal"; - case token_type::literal_null: - return "null literal"; - case token_type::value_string: - return "string literal"; - case token_type::value_unsigned: - case token_type::value_integer: - case token_type::value_float: - return "number literal"; - case token_type::begin_array: - return "'['"; - case token_type::begin_object: - return "'{'"; - case token_type::end_array: - return "']'"; - case token_type::end_object: - return "'}'"; - case token_type::name_separator: - return "':'"; - case token_type::value_separator: - return "','"; - case token_type::parse_error: - return ""; - case token_type::end_of_input: - return "end of input"; - case token_type::literal_or_value: - return "'[', '{', or a literal"; - // LCOV_EXCL_START - default: // catch non-enum values - return "unknown token"; - // LCOV_EXCL_STOP - } - } -}; -/*! -@brief lexical analysis - -This class organizes the lexical analysis during JSON deserialization. -*/ -template -class lexer : public lexer_base -{ - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using number_float_t = typename BasicJsonType::number_float_t; - using string_t = typename BasicJsonType::string_t; - using char_type = typename InputAdapterType::char_type; - using char_int_type = typename std::char_traits::int_type; - - public: - using token_type = typename lexer_base::token_type; - - explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) - : ia(std::move(adapter)) - , ignore_comments(ignore_comments_) - , decimal_point_char(static_cast(get_decimal_point())) - {} - - // delete because of pointer members - lexer(const lexer&) = delete; - lexer(lexer&&) = default; - lexer& operator=(lexer&) = delete; - lexer& operator=(lexer&&) = default; - ~lexer() = default; - - private: - ///////////////////// - // locales - ///////////////////// - - /// return the locale-dependent decimal point - JSON_HEDLEY_PURE - static char get_decimal_point() noexcept - { - const auto* loc = localeconv(); - JSON_ASSERT(loc != nullptr); - return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point); - } - - ///////////////////// - // scan functions - ///////////////////// - - /*! - @brief get codepoint from 4 hex characters following `\u` - - For input "\u c1 c2 c3 c4" the codepoint is: - (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4 - = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0) - - Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f' - must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The - conversion is done by subtracting the offset (0x30, 0x37, and 0x57) - between the ASCII value of the character and the desired integer value. - - @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or - non-hex character) - */ - int get_codepoint() - { - // this function only makes sense after reading `\u` - JSON_ASSERT(current == 'u'); - int codepoint = 0; - - const auto factors = { 12u, 8u, 4u, 0u }; - for (const auto factor : factors) - { - get(); - - if (current >= '0' && current <= '9') - { - codepoint += static_cast((static_cast(current) - 0x30u) << factor); - } - else if (current >= 'A' && current <= 'F') - { - codepoint += static_cast((static_cast(current) - 0x37u) << factor); - } - else if (current >= 'a' && current <= 'f') - { - codepoint += static_cast((static_cast(current) - 0x57u) << factor); - } - else - { - return -1; - } - } - - JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF); - return codepoint; - } - - /*! - @brief check if the next byte(s) are inside a given range - - Adds the current byte and, for each passed range, reads a new byte and - checks if it is inside the range. If a violation was detected, set up an - error message and return false. Otherwise, return true. - - @param[in] ranges list of integers; interpreted as list of pairs of - inclusive lower and upper bound, respectively - - @pre The passed list @a ranges must have 2, 4, or 6 elements; that is, - 1, 2, or 3 pairs. This precondition is enforced by an assertion. - - @return true if and only if no range violation was detected - */ - bool next_byte_in_range(std::initializer_list ranges) - { - JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6); - add(current); - - for (auto range = ranges.begin(); range != ranges.end(); ++range) - { - get(); - if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range))) - { - add(current); - } - else - { - error_message = "invalid string: ill-formed UTF-8 byte"; - return false; - } - } - - return true; - } - - /*! - @brief scan a string literal - - This function scans a string according to Sect. 7 of RFC 7159. While - scanning, bytes are escaped and copied into buffer token_buffer. Then the - function returns successfully, token_buffer is *not* null-terminated (as it - may contain \0 bytes), and token_buffer.size() is the number of bytes in the - string. - - @return token_type::value_string if string could be successfully scanned, - token_type::parse_error otherwise - - @note In case of errors, variable error_message contains a textual - description. - */ - token_type scan_string() - { - // reset token_buffer (ignore opening quote) - reset(); - - // we entered the function by reading an open quote - JSON_ASSERT(current == '\"'); - - while (true) - { - // get next character - switch (get()) - { - // end of file while parsing string - case std::char_traits::eof(): - { - error_message = "invalid string: missing closing quote"; - return token_type::parse_error; - } - - // closing quote - case '\"': - { - return token_type::value_string; - } - - // escapes - case '\\': - { - switch (get()) - { - // quotation mark - case '\"': - add('\"'); - break; - // reverse solidus - case '\\': - add('\\'); - break; - // solidus - case '/': - add('/'); - break; - // backspace - case 'b': - add('\b'); - break; - // form feed - case 'f': - add('\f'); - break; - // line feed - case 'n': - add('\n'); - break; - // carriage return - case 'r': - add('\r'); - break; - // tab - case 't': - add('\t'); - break; - - // unicode escapes - case 'u': - { - const int codepoint1 = get_codepoint(); - int codepoint = codepoint1; // start with codepoint1 - - if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1)) - { - error_message = "invalid string: '\\u' must be followed by 4 hex digits"; - return token_type::parse_error; - } - - // check if code point is a high surrogate - if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF) - { - // expect next \uxxxx entry - if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u')) - { - const int codepoint2 = get_codepoint(); - - if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1)) - { - error_message = "invalid string: '\\u' must be followed by 4 hex digits"; - return token_type::parse_error; - } - - // check if codepoint2 is a low surrogate - if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF)) - { - // overwrite codepoint - codepoint = static_cast( - // high surrogate occupies the most significant 22 bits - (static_cast(codepoint1) << 10u) - // low surrogate occupies the least significant 15 bits - + static_cast(codepoint2) - // there is still the 0xD800, 0xDC00 and 0x10000 noise - // in the result so we have to subtract with: - // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00 - - 0x35FDC00u); - } - else - { - error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF"; - return token_type::parse_error; - } - } - else - { - error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF"; - return token_type::parse_error; - } - } - else - { - if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF)) - { - error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF"; - return token_type::parse_error; - } - } - - // result of the above calculation yields a proper codepoint - JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF); - - // translate codepoint into bytes - if (codepoint < 0x80) - { - // 1-byte characters: 0xxxxxxx (ASCII) - add(static_cast(codepoint)); - } - else if (codepoint <= 0x7FF) - { - // 2-byte characters: 110xxxxx 10xxxxxx - add(static_cast(0xC0u | (static_cast(codepoint) >> 6u))); - add(static_cast(0x80u | (static_cast(codepoint) & 0x3Fu))); - } - else if (codepoint <= 0xFFFF) - { - // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx - add(static_cast(0xE0u | (static_cast(codepoint) >> 12u))); - add(static_cast(0x80u | ((static_cast(codepoint) >> 6u) & 0x3Fu))); - add(static_cast(0x80u | (static_cast(codepoint) & 0x3Fu))); - } - else - { - // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - add(static_cast(0xF0u | (static_cast(codepoint) >> 18u))); - add(static_cast(0x80u | ((static_cast(codepoint) >> 12u) & 0x3Fu))); - add(static_cast(0x80u | ((static_cast(codepoint) >> 6u) & 0x3Fu))); - add(static_cast(0x80u | (static_cast(codepoint) & 0x3Fu))); - } - - break; - } - - // other characters after escape - default: - error_message = "invalid string: forbidden character after backslash"; - return token_type::parse_error; - } - - break; - } - - // invalid control characters - case 0x00: - { - error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000"; - return token_type::parse_error; - } - - case 0x01: - { - error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001"; - return token_type::parse_error; - } - - case 0x02: - { - error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002"; - return token_type::parse_error; - } - - case 0x03: - { - error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003"; - return token_type::parse_error; - } - - case 0x04: - { - error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004"; - return token_type::parse_error; - } - - case 0x05: - { - error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005"; - return token_type::parse_error; - } - - case 0x06: - { - error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006"; - return token_type::parse_error; - } - - case 0x07: - { - error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007"; - return token_type::parse_error; - } - - case 0x08: - { - error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b"; - return token_type::parse_error; - } - - case 0x09: - { - error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t"; - return token_type::parse_error; - } - - case 0x0A: - { - error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n"; - return token_type::parse_error; - } - - case 0x0B: - { - error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B"; - return token_type::parse_error; - } - - case 0x0C: - { - error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f"; - return token_type::parse_error; - } - - case 0x0D: - { - error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r"; - return token_type::parse_error; - } - - case 0x0E: - { - error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E"; - return token_type::parse_error; - } - - case 0x0F: - { - error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F"; - return token_type::parse_error; - } - - case 0x10: - { - error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010"; - return token_type::parse_error; - } - - case 0x11: - { - error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011"; - return token_type::parse_error; - } - - case 0x12: - { - error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012"; - return token_type::parse_error; - } - - case 0x13: - { - error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013"; - return token_type::parse_error; - } - - case 0x14: - { - error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014"; - return token_type::parse_error; - } - - case 0x15: - { - error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015"; - return token_type::parse_error; - } - - case 0x16: - { - error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016"; - return token_type::parse_error; - } - - case 0x17: - { - error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017"; - return token_type::parse_error; - } - - case 0x18: - { - error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018"; - return token_type::parse_error; - } - - case 0x19: - { - error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019"; - return token_type::parse_error; - } - - case 0x1A: - { - error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A"; - return token_type::parse_error; - } - - case 0x1B: - { - error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B"; - return token_type::parse_error; - } - - case 0x1C: - { - error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C"; - return token_type::parse_error; - } - - case 0x1D: - { - error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D"; - return token_type::parse_error; - } - - case 0x1E: - { - error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E"; - return token_type::parse_error; - } - - case 0x1F: - { - error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F"; - return token_type::parse_error; - } - - // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace)) - case 0x20: - case 0x21: - case 0x23: - case 0x24: - case 0x25: - case 0x26: - case 0x27: - case 0x28: - case 0x29: - case 0x2A: - case 0x2B: - case 0x2C: - case 0x2D: - case 0x2E: - case 0x2F: - case 0x30: - case 0x31: - case 0x32: - case 0x33: - case 0x34: - case 0x35: - case 0x36: - case 0x37: - case 0x38: - case 0x39: - case 0x3A: - case 0x3B: - case 0x3C: - case 0x3D: - case 0x3E: - case 0x3F: - case 0x40: - case 0x41: - case 0x42: - case 0x43: - case 0x44: - case 0x45: - case 0x46: - case 0x47: - case 0x48: - case 0x49: - case 0x4A: - case 0x4B: - case 0x4C: - case 0x4D: - case 0x4E: - case 0x4F: - case 0x50: - case 0x51: - case 0x52: - case 0x53: - case 0x54: - case 0x55: - case 0x56: - case 0x57: - case 0x58: - case 0x59: - case 0x5A: - case 0x5B: - case 0x5D: - case 0x5E: - case 0x5F: - case 0x60: - case 0x61: - case 0x62: - case 0x63: - case 0x64: - case 0x65: - case 0x66: - case 0x67: - case 0x68: - case 0x69: - case 0x6A: - case 0x6B: - case 0x6C: - case 0x6D: - case 0x6E: - case 0x6F: - case 0x70: - case 0x71: - case 0x72: - case 0x73: - case 0x74: - case 0x75: - case 0x76: - case 0x77: - case 0x78: - case 0x79: - case 0x7A: - case 0x7B: - case 0x7C: - case 0x7D: - case 0x7E: - case 0x7F: - { - add(current); - break; - } - - // U+0080..U+07FF: bytes C2..DF 80..BF - case 0xC2: - case 0xC3: - case 0xC4: - case 0xC5: - case 0xC6: - case 0xC7: - case 0xC8: - case 0xC9: - case 0xCA: - case 0xCB: - case 0xCC: - case 0xCD: - case 0xCE: - case 0xCF: - case 0xD0: - case 0xD1: - case 0xD2: - case 0xD3: - case 0xD4: - case 0xD5: - case 0xD6: - case 0xD7: - case 0xD8: - case 0xD9: - case 0xDA: - case 0xDB: - case 0xDC: - case 0xDD: - case 0xDE: - case 0xDF: - { - if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF}))) - { - return token_type::parse_error; - } - break; - } - - // U+0800..U+0FFF: bytes E0 A0..BF 80..BF - case 0xE0: - { - if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF})))) - { - return token_type::parse_error; - } - break; - } - - // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF - // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF - case 0xE1: - case 0xE2: - case 0xE3: - case 0xE4: - case 0xE5: - case 0xE6: - case 0xE7: - case 0xE8: - case 0xE9: - case 0xEA: - case 0xEB: - case 0xEC: - case 0xEE: - case 0xEF: - { - if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF})))) - { - return token_type::parse_error; - } - break; - } - - // U+D000..U+D7FF: bytes ED 80..9F 80..BF - case 0xED: - { - if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF})))) - { - return token_type::parse_error; - } - break; - } - - // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF - case 0xF0: - { - if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF})))) - { - return token_type::parse_error; - } - break; - } - - // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF - case 0xF1: - case 0xF2: - case 0xF3: - { - if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF})))) - { - return token_type::parse_error; - } - break; - } - - // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF - case 0xF4: - { - if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF})))) - { - return token_type::parse_error; - } - break; - } - - // remaining bytes (80..C1 and F5..FF) are ill-formed - default: - { - error_message = "invalid string: ill-formed UTF-8 byte"; - return token_type::parse_error; - } - } - } - } - - /*! - * @brief scan a comment - * @return whether comment could be scanned successfully - */ - bool scan_comment() - { - switch (get()) - { - // single-line comments skip input until a newline or EOF is read - case '/': - { - while (true) - { - switch (get()) - { - case '\n': - case '\r': - case std::char_traits::eof(): - case '\0': - return true; - - default: - break; - } - } - } - - // multi-line comments skip input until */ is read - case '*': - { - while (true) - { - switch (get()) - { - case std::char_traits::eof(): - case '\0': - { - error_message = "invalid comment; missing closing '*/'"; - return false; - } - - case '*': - { - switch (get()) - { - case '/': - return true; - - default: - { - unget(); - continue; - } - } - } - - default: - continue; - } - } - } - - // unexpected character after reading '/' - default: - { - error_message = "invalid comment; expecting '/' or '*' after '/'"; - return false; - } - } - } - - JSON_HEDLEY_NON_NULL(2) - static void strtof(float& f, const char* str, char** endptr) noexcept - { - f = std::strtof(str, endptr); - } - - JSON_HEDLEY_NON_NULL(2) - static void strtof(double& f, const char* str, char** endptr) noexcept - { - f = std::strtod(str, endptr); - } - - JSON_HEDLEY_NON_NULL(2) - static void strtof(long double& f, const char* str, char** endptr) noexcept - { - f = std::strtold(str, endptr); - } - - /*! - @brief scan a number literal - - This function scans a string according to Sect. 6 of RFC 7159. - - The function is realized with a deterministic finite state machine derived - from the grammar described in RFC 7159. Starting in state "init", the - input is read and used to determined the next state. Only state "done" - accepts the number. State "error" is a trap state to model errors. In the - table below, "anything" means any character but the ones listed before. - - state | 0 | 1-9 | e E | + | - | . | anything - ---------|----------|----------|----------|---------|---------|----------|----------- - init | zero | any1 | [error] | [error] | minus | [error] | [error] - minus | zero | any1 | [error] | [error] | [error] | [error] | [error] - zero | done | done | exponent | done | done | decimal1 | done - any1 | any1 | any1 | exponent | done | done | decimal1 | done - decimal1 | decimal2 | decimal2 | [error] | [error] | [error] | [error] | [error] - decimal2 | decimal2 | decimal2 | exponent | done | done | done | done - exponent | any2 | any2 | [error] | sign | sign | [error] | [error] - sign | any2 | any2 | [error] | [error] | [error] | [error] | [error] - any2 | any2 | any2 | done | done | done | done | done - - The state machine is realized with one label per state (prefixed with - "scan_number_") and `goto` statements between them. The state machine - contains cycles, but any cycle can be left when EOF is read. Therefore, - the function is guaranteed to terminate. - - During scanning, the read bytes are stored in token_buffer. This string is - then converted to a signed integer, an unsigned integer, or a - floating-point number. - - @return token_type::value_unsigned, token_type::value_integer, or - token_type::value_float if number could be successfully scanned, - token_type::parse_error otherwise - - @note The scanner is independent of the current locale. Internally, the - locale's decimal point is used instead of `.` to work with the - locale-dependent converters. - */ - token_type scan_number() // lgtm [cpp/use-of-goto] - { - // reset token_buffer to store the number's bytes - reset(); - - // the type of the parsed number; initially set to unsigned; will be - // changed if minus sign, decimal point or exponent is read - token_type number_type = token_type::value_unsigned; - - // state (init): we just found out we need to scan a number - switch (current) - { - case '-': - { - add(current); - goto scan_number_minus; - } - - case '0': - { - add(current); - goto scan_number_zero; - } - - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - add(current); - goto scan_number_any1; - } - - // all other characters are rejected outside scan_number() - default: // LCOV_EXCL_LINE - JSON_ASSERT(false); // LCOV_EXCL_LINE - } - -scan_number_minus: - // state: we just parsed a leading minus sign - number_type = token_type::value_integer; - switch (get()) - { - case '0': - { - add(current); - goto scan_number_zero; - } - - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - add(current); - goto scan_number_any1; - } - - default: - { - error_message = "invalid number; expected digit after '-'"; - return token_type::parse_error; - } - } - -scan_number_zero: - // state: we just parse a zero (maybe with a leading minus sign) - switch (get()) - { - case '.': - { - add(decimal_point_char); - goto scan_number_decimal1; - } - - case 'e': - case 'E': - { - add(current); - goto scan_number_exponent; - } - - default: - goto scan_number_done; - } - -scan_number_any1: - // state: we just parsed a number 0-9 (maybe with a leading minus sign) - switch (get()) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - add(current); - goto scan_number_any1; - } - - case '.': - { - add(decimal_point_char); - goto scan_number_decimal1; - } - - case 'e': - case 'E': - { - add(current); - goto scan_number_exponent; - } - - default: - goto scan_number_done; - } - -scan_number_decimal1: - // state: we just parsed a decimal point - number_type = token_type::value_float; - switch (get()) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - add(current); - goto scan_number_decimal2; - } - - default: - { - error_message = "invalid number; expected digit after '.'"; - return token_type::parse_error; - } - } - -scan_number_decimal2: - // we just parsed at least one number after a decimal point - switch (get()) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - add(current); - goto scan_number_decimal2; - } - - case 'e': - case 'E': - { - add(current); - goto scan_number_exponent; - } - - default: - goto scan_number_done; - } - -scan_number_exponent: - // we just parsed an exponent - number_type = token_type::value_float; - switch (get()) - { - case '+': - case '-': - { - add(current); - goto scan_number_sign; - } - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - add(current); - goto scan_number_any2; - } - - default: - { - error_message = - "invalid number; expected '+', '-', or digit after exponent"; - return token_type::parse_error; - } - } - -scan_number_sign: - // we just parsed an exponent sign - switch (get()) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - add(current); - goto scan_number_any2; - } - - default: - { - error_message = "invalid number; expected digit after exponent sign"; - return token_type::parse_error; - } - } - -scan_number_any2: - // we just parsed a number after the exponent or exponent sign - switch (get()) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - add(current); - goto scan_number_any2; - } - - default: - goto scan_number_done; - } - -scan_number_done: - // unget the character after the number (we only read it to know that - // we are done scanning a number) - unget(); - - char* endptr = nullptr; - errno = 0; - - // try to parse integers first and fall back to floats - if (number_type == token_type::value_unsigned) - { - const auto x = std::strtoull(token_buffer.data(), &endptr, 10); - - // we checked the number format before - JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size()); - - if (errno == 0) - { - value_unsigned = static_cast(x); - if (value_unsigned == x) - { - return token_type::value_unsigned; - } - } - } - else if (number_type == token_type::value_integer) - { - const auto x = std::strtoll(token_buffer.data(), &endptr, 10); - - // we checked the number format before - JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size()); - - if (errno == 0) - { - value_integer = static_cast(x); - if (value_integer == x) - { - return token_type::value_integer; - } - } - } - - // this code is reached if we parse a floating-point number or if an - // integer conversion above failed - strtof(value_float, token_buffer.data(), &endptr); - - // we checked the number format before - JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size()); - - return token_type::value_float; - } - - /*! - @param[in] literal_text the literal text to expect - @param[in] length the length of the passed literal text - @param[in] return_type the token type to return on success - */ - JSON_HEDLEY_NON_NULL(2) - token_type scan_literal(const char_type* literal_text, const std::size_t length, - token_type return_type) - { - JSON_ASSERT(std::char_traits::to_char_type(current) == literal_text[0]); - for (std::size_t i = 1; i < length; ++i) - { - if (JSON_HEDLEY_UNLIKELY(std::char_traits::to_char_type(get()) != literal_text[i])) - { - error_message = "invalid literal"; - return token_type::parse_error; - } - } - return return_type; - } - - ///////////////////// - // input management - ///////////////////// - - /// reset token_buffer; current character is beginning of token - void reset() noexcept - { - token_buffer.clear(); - token_string.clear(); - token_string.push_back(std::char_traits::to_char_type(current)); - } - - /* - @brief get next character from the input - - This function provides the interface to the used input adapter. It does - not throw in case the input reached EOF, but returns a - `std::char_traits::eof()` in that case. Stores the scanned characters - for use in error messages. - - @return character read from the input - */ - char_int_type get() - { - ++position.chars_read_total; - ++position.chars_read_current_line; - - if (next_unget) - { - // just reset the next_unget variable and work with current - next_unget = false; - } - else - { - current = ia.get_character(); - } - - if (JSON_HEDLEY_LIKELY(current != std::char_traits::eof())) - { - token_string.push_back(std::char_traits::to_char_type(current)); - } - - if (current == '\n') - { - ++position.lines_read; - position.chars_read_current_line = 0; - } - - return current; - } - - /*! - @brief unget current character (read it again on next get) - - We implement unget by setting variable next_unget to true. The input is not - changed - we just simulate ungetting by modifying chars_read_total, - chars_read_current_line, and token_string. The next call to get() will - behave as if the unget character is read again. - */ - void unget() - { - next_unget = true; - - --position.chars_read_total; - - // in case we "unget" a newline, we have to also decrement the lines_read - if (position.chars_read_current_line == 0) - { - if (position.lines_read > 0) - { - --position.lines_read; - } - } - else - { - --position.chars_read_current_line; - } - - if (JSON_HEDLEY_LIKELY(current != std::char_traits::eof())) - { - JSON_ASSERT(!token_string.empty()); - token_string.pop_back(); - } - } - - /// add a character to token_buffer - void add(char_int_type c) - { - token_buffer.push_back(static_cast(c)); - } - - public: - ///////////////////// - // value getters - ///////////////////// - - /// return integer value - constexpr number_integer_t get_number_integer() const noexcept - { - return value_integer; - } - - /// return unsigned integer value - constexpr number_unsigned_t get_number_unsigned() const noexcept - { - return value_unsigned; - } - - /// return floating-point value - constexpr number_float_t get_number_float() const noexcept - { - return value_float; - } - - /// return current string value (implicitly resets the token; useful only once) - string_t& get_string() - { - return token_buffer; - } - - ///////////////////// - // diagnostics - ///////////////////// - - /// return position of last read token - constexpr position_t get_position() const noexcept - { - return position; - } - - /// return the last read token (for errors only). Will never contain EOF - /// (an arbitrary value that is not a valid char value, often -1), because - /// 255 may legitimately occur. May contain NUL, which should be escaped. - std::string get_token_string() const - { - // escape control characters - std::string result; - for (const auto c : token_string) - { - if (static_cast(c) <= '\x1F') - { - // escape control characters - std::array cs{{}}; - (std::snprintf)(cs.data(), cs.size(), "", static_cast(c)); - result += cs.data(); - } - else - { - // add character as is - result.push_back(static_cast(c)); - } - } - - return result; - } - - /// return syntax error message - JSON_HEDLEY_RETURNS_NON_NULL - constexpr const char* get_error_message() const noexcept - { - return error_message; - } - - ///////////////////// - // actual scanner - ///////////////////// - - /*! - @brief skip the UTF-8 byte order mark - @return true iff there is no BOM or the correct BOM has been skipped - */ - bool skip_bom() - { - if (get() == 0xEF) - { - // check if we completely parse the BOM - return get() == 0xBB && get() == 0xBF; - } - - // the first character is not the beginning of the BOM; unget it to - // process is later - unget(); - return true; - } - - void skip_whitespace() - { - do - { - get(); - } - while (current == ' ' || current == '\t' || current == '\n' || current == '\r'); - } - - token_type scan() - { - // initially, skip the BOM - if (position.chars_read_total == 0 && !skip_bom()) - { - error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given"; - return token_type::parse_error; - } - - // read next character and ignore whitespace - skip_whitespace(); - - // ignore comments - while (ignore_comments && current == '/') - { - if (!scan_comment()) - { - return token_type::parse_error; - } - - // skip following whitespace - skip_whitespace(); - } - - switch (current) - { - // structural characters - case '[': - return token_type::begin_array; - case ']': - return token_type::end_array; - case '{': - return token_type::begin_object; - case '}': - return token_type::end_object; - case ':': - return token_type::name_separator; - case ',': - return token_type::value_separator; - - // literals - case 't': - { - std::array true_literal = {{'t', 'r', 'u', 'e'}}; - return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true); - } - case 'f': - { - std::array false_literal = {{'f', 'a', 'l', 's', 'e'}}; - return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false); - } - case 'n': - { - std::array null_literal = {{'n', 'u', 'l', 'l'}}; - return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null); - } - - // string - case '\"': - return scan_string(); - - // number - case '-': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - return scan_number(); - - // end of input (the null byte is needed when parsing from - // string literals) - case '\0': - case std::char_traits::eof(): - return token_type::end_of_input; - - // error - default: - error_message = "invalid literal"; - return token_type::parse_error; - } - } - - private: - /// input adapter - InputAdapterType ia; - - /// whether comments should be ignored (true) or signaled as errors (false) - const bool ignore_comments = false; - - /// the current character - char_int_type current = std::char_traits::eof(); - - /// whether the next get() call should just return current - bool next_unget = false; - - /// the start position of the current token - position_t position {}; - - /// raw input token string (for error messages) - std::vector token_string {}; - - /// buffer for variable-length tokens (numbers, strings) - string_t token_buffer {}; - - /// a description of occurred lexer errors - const char* error_message = ""; - - // number values - number_integer_t value_integer = 0; - number_unsigned_t value_unsigned = 0; - number_float_t value_float = 0; - - /// the decimal point - const char_int_type decimal_point_char = '.'; -}; -} // namespace detail -} // namespace nlohmann - -// #include - -// #include - - -#include // size_t -#include // declval -#include // string - -// #include - -// #include - - -namespace nlohmann -{ -namespace detail -{ -template -using null_function_t = decltype(std::declval().null()); - -template -using boolean_function_t = - decltype(std::declval().boolean(std::declval())); - -template -using number_integer_function_t = - decltype(std::declval().number_integer(std::declval())); - -template -using number_unsigned_function_t = - decltype(std::declval().number_unsigned(std::declval())); - -template -using number_float_function_t = decltype(std::declval().number_float( - std::declval(), std::declval())); - -template -using string_function_t = - decltype(std::declval().string(std::declval())); - -template -using binary_function_t = - decltype(std::declval().binary(std::declval())); - -template -using start_object_function_t = - decltype(std::declval().start_object(std::declval())); - -template -using key_function_t = - decltype(std::declval().key(std::declval())); - -template -using end_object_function_t = decltype(std::declval().end_object()); - -template -using start_array_function_t = - decltype(std::declval().start_array(std::declval())); - -template -using end_array_function_t = decltype(std::declval().end_array()); - -template -using parse_error_function_t = decltype(std::declval().parse_error( - std::declval(), std::declval(), - std::declval())); - -template -struct is_sax -{ - private: - static_assert(is_basic_json::value, - "BasicJsonType must be of type basic_json<...>"); - - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using number_float_t = typename BasicJsonType::number_float_t; - using string_t = typename BasicJsonType::string_t; - using binary_t = typename BasicJsonType::binary_t; - using exception_t = typename BasicJsonType::exception; - - public: - static constexpr bool value = - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value; -}; - -template -struct is_sax_static_asserts -{ - private: - static_assert(is_basic_json::value, - "BasicJsonType must be of type basic_json<...>"); - - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using number_float_t = typename BasicJsonType::number_float_t; - using string_t = typename BasicJsonType::string_t; - using binary_t = typename BasicJsonType::binary_t; - using exception_t = typename BasicJsonType::exception; - - public: - static_assert(is_detected_exact::value, - "Missing/invalid function: bool null()"); - static_assert(is_detected_exact::value, - "Missing/invalid function: bool boolean(bool)"); - static_assert(is_detected_exact::value, - "Missing/invalid function: bool boolean(bool)"); - static_assert( - is_detected_exact::value, - "Missing/invalid function: bool number_integer(number_integer_t)"); - static_assert( - is_detected_exact::value, - "Missing/invalid function: bool number_unsigned(number_unsigned_t)"); - static_assert(is_detected_exact::value, - "Missing/invalid function: bool number_float(number_float_t, const string_t&)"); - static_assert( - is_detected_exact::value, - "Missing/invalid function: bool string(string_t&)"); - static_assert( - is_detected_exact::value, - "Missing/invalid function: bool binary(binary_t&)"); - static_assert(is_detected_exact::value, - "Missing/invalid function: bool start_object(std::size_t)"); - static_assert(is_detected_exact::value, - "Missing/invalid function: bool key(string_t&)"); - static_assert(is_detected_exact::value, - "Missing/invalid function: bool end_object()"); - static_assert(is_detected_exact::value, - "Missing/invalid function: bool start_array(std::size_t)"); - static_assert(is_detected_exact::value, - "Missing/invalid function: bool end_array()"); - static_assert( - is_detected_exact::value, - "Missing/invalid function: bool parse_error(std::size_t, const " - "std::string&, const exception&)"); -}; -} // namespace detail -} // namespace nlohmann - -// #include - - -namespace nlohmann -{ -namespace detail -{ - -/// how to treat CBOR tags -enum class cbor_tag_handler_t -{ - error, ///< throw a parse_error exception in case of a tag - ignore ///< ignore tags -}; - -/*! -@brief determine system byte order - -@return true if and only if system's byte order is little endian - -@note from https://stackoverflow.com/a/1001328/266378 -*/ -static inline bool little_endianess(int num = 1) noexcept -{ - return *reinterpret_cast(&num) == 1; -} - - -/////////////////// -// binary reader // -/////////////////// - -/*! -@brief deserialization of CBOR, MessagePack, and UBJSON values -*/ -template> -class binary_reader -{ - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using number_float_t = typename BasicJsonType::number_float_t; - using string_t = typename BasicJsonType::string_t; - using binary_t = typename BasicJsonType::binary_t; - using json_sax_t = SAX; - using char_type = typename InputAdapterType::char_type; - using char_int_type = typename std::char_traits::int_type; - - public: - /*! - @brief create a binary reader - - @param[in] adapter input adapter to read from - */ - explicit binary_reader(InputAdapterType&& adapter) : ia(std::move(adapter)) - { - (void)detail::is_sax_static_asserts {}; - } - - // make class move-only - binary_reader(const binary_reader&) = delete; - binary_reader(binary_reader&&) = default; - binary_reader& operator=(const binary_reader&) = delete; - binary_reader& operator=(binary_reader&&) = default; - ~binary_reader() = default; - - /*! - @param[in] format the binary format to parse - @param[in] sax_ a SAX event processor - @param[in] strict whether to expect the input to be consumed completed - @param[in] tag_handler how to treat CBOR tags - - @return - */ - JSON_HEDLEY_NON_NULL(3) - bool sax_parse(const input_format_t format, - json_sax_t* sax_, - const bool strict = true, - const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) - { - sax = sax_; - bool result = false; - - switch (format) - { - case input_format_t::bson: - result = parse_bson_internal(); - break; - - case input_format_t::cbor: - result = parse_cbor_internal(true, tag_handler); - break; - - case input_format_t::msgpack: - result = parse_msgpack_internal(); - break; - - case input_format_t::ubjson: - result = parse_ubjson_internal(); - break; - - default: // LCOV_EXCL_LINE - JSON_ASSERT(false); // LCOV_EXCL_LINE - } - - // strict mode: next byte must be EOF - if (result && strict) - { - if (format == input_format_t::ubjson) - { - get_ignore_noop(); - } - else - { - get(); - } - - if (JSON_HEDLEY_UNLIKELY(current != std::char_traits::eof())) - { - return sax->parse_error(chars_read, get_token_string(), - parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value"))); - } - } - - return result; - } - - private: - ////////// - // BSON // - ////////// - - /*! - @brief Reads in a BSON-object and passes it to the SAX-parser. - @return whether a valid BSON-value was passed to the SAX parser - */ - bool parse_bson_internal() - { - std::int32_t document_size{}; - get_number(input_format_t::bson, document_size); - - if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1)))) - { - return false; - } - - if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false))) - { - return false; - } - - return sax->end_object(); - } - - /*! - @brief Parses a C-style string from the BSON input. - @param[in, out] result A reference to the string variable where the read - string is to be stored. - @return `true` if the \x00-byte indicating the end of the string was - encountered before the EOF; false` indicates an unexpected EOF. - */ - bool get_bson_cstr(string_t& result) - { - auto out = std::back_inserter(result); - while (true) - { - get(); - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring"))) - { - return false; - } - if (current == 0x00) - { - return true; - } - *out++ = static_cast(current); - } - } - - /*! - @brief Parses a zero-terminated string of length @a len from the BSON - input. - @param[in] len The length (including the zero-byte at the end) of the - string to be read. - @param[in, out] result A reference to the string variable where the read - string is to be stored. - @tparam NumberType The type of the length @a len - @pre len >= 1 - @return `true` if the string was successfully parsed - */ - template - bool get_bson_string(const NumberType len, string_t& result) - { - if (JSON_HEDLEY_UNLIKELY(len < 1)) - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "string length must be at least 1, is " + std::to_string(len), "string"))); - } - - return get_string(input_format_t::bson, len - static_cast(1), result) && get() != std::char_traits::eof(); - } - - /*! - @brief Parses a byte array input of length @a len from the BSON input. - @param[in] len The length of the byte array to be read. - @param[in, out] result A reference to the binary variable where the read - array is to be stored. - @tparam NumberType The type of the length @a len - @pre len >= 0 - @return `true` if the byte array was successfully parsed - */ - template - bool get_bson_binary(const NumberType len, binary_t& result) - { - if (JSON_HEDLEY_UNLIKELY(len < 0)) - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "byte array length cannot be negative, is " + std::to_string(len), "binary"))); - } - - // All BSON binary values have a subtype - std::uint8_t subtype{}; - get_number(input_format_t::bson, subtype); - result.set_subtype(subtype); - - return get_binary(input_format_t::bson, len, result); - } - - /*! - @brief Read a BSON document element of the given @a element_type. - @param[in] element_type The BSON element type, c.f. http://bsonspec.org/spec.html - @param[in] element_type_parse_position The position in the input stream, - where the `element_type` was read. - @warning Not all BSON element types are supported yet. An unsupported - @a element_type will give rise to a parse_error.114: - Unsupported BSON record type 0x... - @return whether a valid BSON-object/array was passed to the SAX parser - */ - bool parse_bson_element_internal(const char_int_type element_type, - const std::size_t element_type_parse_position) - { - switch (element_type) - { - case 0x01: // double - { - double number{}; - return get_number(input_format_t::bson, number) && sax->number_float(static_cast(number), ""); - } - - case 0x02: // string - { - std::int32_t len{}; - string_t value; - return get_number(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value); - } - - case 0x03: // object - { - return parse_bson_internal(); - } - - case 0x04: // array - { - return parse_bson_array(); - } - - case 0x05: // binary - { - std::int32_t len{}; - binary_t value; - return get_number(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value); - } - - case 0x08: // boolean - { - return sax->boolean(get() != 0); - } - - case 0x0A: // null - { - return sax->null(); - } - - case 0x10: // int32 - { - std::int32_t value{}; - return get_number(input_format_t::bson, value) && sax->number_integer(value); - } - - case 0x12: // int64 - { - std::int64_t value{}; - return get_number(input_format_t::bson, value) && sax->number_integer(value); - } - - default: // anything else not supported (yet) - { - std::array cr{{}}; - (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast(element_type)); - return sax->parse_error(element_type_parse_position, std::string(cr.data()), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr.data()))); - } - } - } - - /*! - @brief Read a BSON element list (as specified in the BSON-spec) - - The same binary layout is used for objects and arrays, hence it must be - indicated with the argument @a is_array which one is expected - (true --> array, false --> object). - - @param[in] is_array Determines if the element list being read is to be - treated as an object (@a is_array == false), or as an - array (@a is_array == true). - @return whether a valid BSON-object/array was passed to the SAX parser - */ - bool parse_bson_element_list(const bool is_array) - { - string_t key; - - while (auto element_type = get()) - { - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list"))) - { - return false; - } - - const std::size_t element_type_parse_position = chars_read; - if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key))) - { - return false; - } - - if (!is_array && !sax->key(key)) - { - return false; - } - - if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position))) - { - return false; - } - - // get_bson_cstr only appends - key.clear(); - } - - return true; - } - - /*! - @brief Reads an array from the BSON input and passes it to the SAX-parser. - @return whether a valid BSON-array was passed to the SAX parser - */ - bool parse_bson_array() - { - std::int32_t document_size{}; - get_number(input_format_t::bson, document_size); - - if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1)))) - { - return false; - } - - if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true))) - { - return false; - } - - return sax->end_array(); - } - - ////////// - // CBOR // - ////////// - - /*! - @param[in] get_char whether a new character should be retrieved from the - input (true) or whether the last read character should - be considered instead (false) - @param[in] tag_handler how CBOR tags should be treated - - @return whether a valid CBOR value was passed to the SAX parser - */ - bool parse_cbor_internal(const bool get_char, - const cbor_tag_handler_t tag_handler) - { - switch (get_char ? get() : current) - { - // EOF - case std::char_traits::eof(): - return unexpect_eof(input_format_t::cbor, "value"); - - // Integer 0x00..0x17 (0..23) - case 0x00: - case 0x01: - case 0x02: - case 0x03: - case 0x04: - case 0x05: - case 0x06: - case 0x07: - case 0x08: - case 0x09: - case 0x0A: - case 0x0B: - case 0x0C: - case 0x0D: - case 0x0E: - case 0x0F: - case 0x10: - case 0x11: - case 0x12: - case 0x13: - case 0x14: - case 0x15: - case 0x16: - case 0x17: - return sax->number_unsigned(static_cast(current)); - - case 0x18: // Unsigned integer (one-byte uint8_t follows) - { - std::uint8_t number{}; - return get_number(input_format_t::cbor, number) && sax->number_unsigned(number); - } - - case 0x19: // Unsigned integer (two-byte uint16_t follows) - { - std::uint16_t number{}; - return get_number(input_format_t::cbor, number) && sax->number_unsigned(number); - } - - case 0x1A: // Unsigned integer (four-byte uint32_t follows) - { - std::uint32_t number{}; - return get_number(input_format_t::cbor, number) && sax->number_unsigned(number); - } - - case 0x1B: // Unsigned integer (eight-byte uint64_t follows) - { - std::uint64_t number{}; - return get_number(input_format_t::cbor, number) && sax->number_unsigned(number); - } - - // Negative integer -1-0x00..-1-0x17 (-1..-24) - case 0x20: - case 0x21: - case 0x22: - case 0x23: - case 0x24: - case 0x25: - case 0x26: - case 0x27: - case 0x28: - case 0x29: - case 0x2A: - case 0x2B: - case 0x2C: - case 0x2D: - case 0x2E: - case 0x2F: - case 0x30: - case 0x31: - case 0x32: - case 0x33: - case 0x34: - case 0x35: - case 0x36: - case 0x37: - return sax->number_integer(static_cast(0x20 - 1 - current)); - - case 0x38: // Negative integer (one-byte uint8_t follows) - { - std::uint8_t number{}; - return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast(-1) - number); - } - - case 0x39: // Negative integer -1-n (two-byte uint16_t follows) - { - std::uint16_t number{}; - return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast(-1) - number); - } - - case 0x3A: // Negative integer -1-n (four-byte uint32_t follows) - { - std::uint32_t number{}; - return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast(-1) - number); - } - - case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows) - { - std::uint64_t number{}; - return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast(-1) - - static_cast(number)); - } - - // Binary data (0x00..0x17 bytes follow) - case 0x40: - case 0x41: - case 0x42: - case 0x43: - case 0x44: - case 0x45: - case 0x46: - case 0x47: - case 0x48: - case 0x49: - case 0x4A: - case 0x4B: - case 0x4C: - case 0x4D: - case 0x4E: - case 0x4F: - case 0x50: - case 0x51: - case 0x52: - case 0x53: - case 0x54: - case 0x55: - case 0x56: - case 0x57: - case 0x58: // Binary data (one-byte uint8_t for n follows) - case 0x59: // Binary data (two-byte uint16_t for n follow) - case 0x5A: // Binary data (four-byte uint32_t for n follow) - case 0x5B: // Binary data (eight-byte uint64_t for n follow) - case 0x5F: // Binary data (indefinite length) - { - binary_t b; - return get_cbor_binary(b) && sax->binary(b); - } - - // UTF-8 string (0x00..0x17 bytes follow) - case 0x60: - case 0x61: - case 0x62: - case 0x63: - case 0x64: - case 0x65: - case 0x66: - case 0x67: - case 0x68: - case 0x69: - case 0x6A: - case 0x6B: - case 0x6C: - case 0x6D: - case 0x6E: - case 0x6F: - case 0x70: - case 0x71: - case 0x72: - case 0x73: - case 0x74: - case 0x75: - case 0x76: - case 0x77: - case 0x78: // UTF-8 string (one-byte uint8_t for n follows) - case 0x79: // UTF-8 string (two-byte uint16_t for n follow) - case 0x7A: // UTF-8 string (four-byte uint32_t for n follow) - case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow) - case 0x7F: // UTF-8 string (indefinite length) - { - string_t s; - return get_cbor_string(s) && sax->string(s); - } - - // array (0x00..0x17 data items follow) - case 0x80: - case 0x81: - case 0x82: - case 0x83: - case 0x84: - case 0x85: - case 0x86: - case 0x87: - case 0x88: - case 0x89: - case 0x8A: - case 0x8B: - case 0x8C: - case 0x8D: - case 0x8E: - case 0x8F: - case 0x90: - case 0x91: - case 0x92: - case 0x93: - case 0x94: - case 0x95: - case 0x96: - case 0x97: - return get_cbor_array(static_cast(static_cast(current) & 0x1Fu), tag_handler); - - case 0x98: // array (one-byte uint8_t for n follows) - { - std::uint8_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len), tag_handler); - } - - case 0x99: // array (two-byte uint16_t for n follow) - { - std::uint16_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len), tag_handler); - } - - case 0x9A: // array (four-byte uint32_t for n follow) - { - std::uint32_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len), tag_handler); - } - - case 0x9B: // array (eight-byte uint64_t for n follow) - { - std::uint64_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len), tag_handler); - } - - case 0x9F: // array (indefinite length) - return get_cbor_array(std::size_t(-1), tag_handler); - - // map (0x00..0x17 pairs of data items follow) - case 0xA0: - case 0xA1: - case 0xA2: - case 0xA3: - case 0xA4: - case 0xA5: - case 0xA6: - case 0xA7: - case 0xA8: - case 0xA9: - case 0xAA: - case 0xAB: - case 0xAC: - case 0xAD: - case 0xAE: - case 0xAF: - case 0xB0: - case 0xB1: - case 0xB2: - case 0xB3: - case 0xB4: - case 0xB5: - case 0xB6: - case 0xB7: - return get_cbor_object(static_cast(static_cast(current) & 0x1Fu), tag_handler); - - case 0xB8: // map (one-byte uint8_t for n follows) - { - std::uint8_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len), tag_handler); - } - - case 0xB9: // map (two-byte uint16_t for n follow) - { - std::uint16_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len), tag_handler); - } - - case 0xBA: // map (four-byte uint32_t for n follow) - { - std::uint32_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len), tag_handler); - } - - case 0xBB: // map (eight-byte uint64_t for n follow) - { - std::uint64_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len), tag_handler); - } - - case 0xBF: // map (indefinite length) - return get_cbor_object(std::size_t(-1), tag_handler); - - case 0xC6: // tagged item - case 0xC7: - case 0xC8: - case 0xC9: - case 0xCA: - case 0xCB: - case 0xCC: - case 0xCD: - case 0xCE: - case 0xCF: - case 0xD0: - case 0xD1: - case 0xD2: - case 0xD3: - case 0xD4: - case 0xD8: // tagged item (1 bytes follow) - case 0xD9: // tagged item (2 bytes follow) - case 0xDA: // tagged item (4 bytes follow) - case 0xDB: // tagged item (8 bytes follow) - { - switch (tag_handler) - { - case cbor_tag_handler_t::error: - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value"))); - } - - case cbor_tag_handler_t::ignore: - { - switch (current) - { - case 0xD8: - { - std::uint8_t len{}; - get_number(input_format_t::cbor, len); - break; - } - case 0xD9: - { - std::uint16_t len{}; - get_number(input_format_t::cbor, len); - break; - } - case 0xDA: - { - std::uint32_t len{}; - get_number(input_format_t::cbor, len); - break; - } - case 0xDB: - { - std::uint64_t len{}; - get_number(input_format_t::cbor, len); - break; - } - default: - break; - } - return parse_cbor_internal(true, tag_handler); - } - - default: // LCOV_EXCL_LINE - JSON_ASSERT(false); // LCOV_EXCL_LINE - } - } - - case 0xF4: // false - return sax->boolean(false); - - case 0xF5: // true - return sax->boolean(true); - - case 0xF6: // null - return sax->null(); - - case 0xF9: // Half-Precision Float (two-byte IEEE 754) - { - const auto byte1_raw = get(); - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number"))) - { - return false; - } - const auto byte2_raw = get(); - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number"))) - { - return false; - } - - const auto byte1 = static_cast(byte1_raw); - const auto byte2 = static_cast(byte2_raw); - - // code from RFC 7049, Appendix D, Figure 3: - // As half-precision floating-point numbers were only added - // to IEEE 754 in 2008, today's programming platforms often - // still only have limited support for them. It is very - // easy to include at least decoding support for them even - // without such support. An example of a small decoder for - // half-precision floating-point numbers in the C language - // is shown in Fig. 3. - const auto half = static_cast((byte1 << 8u) + byte2); - const double val = [&half] - { - const int exp = (half >> 10u) & 0x1Fu; - const unsigned int mant = half & 0x3FFu; - JSON_ASSERT(0 <= exp&& exp <= 32); - JSON_ASSERT(mant <= 1024); - switch (exp) - { - case 0: - return std::ldexp(mant, -24); - case 31: - return (mant == 0) - ? std::numeric_limits::infinity() - : std::numeric_limits::quiet_NaN(); - default: - return std::ldexp(mant + 1024, exp - 25); - } - }(); - return sax->number_float((half & 0x8000u) != 0 - ? static_cast(-val) - : static_cast(val), ""); - } - - case 0xFA: // Single-Precision Float (four-byte IEEE 754) - { - float number{}; - return get_number(input_format_t::cbor, number) && sax->number_float(static_cast(number), ""); - } - - case 0xFB: // Double-Precision Float (eight-byte IEEE 754) - { - double number{}; - return get_number(input_format_t::cbor, number) && sax->number_float(static_cast(number), ""); - } - - default: // anything else (0xFF is handled inside the other types) - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value"))); - } - } - } - - /*! - @brief reads a CBOR string - - This function first reads starting bytes to determine the expected - string length and then copies this number of bytes into a string. - Additionally, CBOR's strings with indefinite lengths are supported. - - @param[out] result created string - - @return whether string creation completed - */ - bool get_cbor_string(string_t& result) - { - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string"))) - { - return false; - } - - switch (current) - { - // UTF-8 string (0x00..0x17 bytes follow) - case 0x60: - case 0x61: - case 0x62: - case 0x63: - case 0x64: - case 0x65: - case 0x66: - case 0x67: - case 0x68: - case 0x69: - case 0x6A: - case 0x6B: - case 0x6C: - case 0x6D: - case 0x6E: - case 0x6F: - case 0x70: - case 0x71: - case 0x72: - case 0x73: - case 0x74: - case 0x75: - case 0x76: - case 0x77: - { - return get_string(input_format_t::cbor, static_cast(current) & 0x1Fu, result); - } - - case 0x78: // UTF-8 string (one-byte uint8_t for n follows) - { - std::uint8_t len{}; - return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result); - } - - case 0x79: // UTF-8 string (two-byte uint16_t for n follow) - { - std::uint16_t len{}; - return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result); - } - - case 0x7A: // UTF-8 string (four-byte uint32_t for n follow) - { - std::uint32_t len{}; - return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result); - } - - case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow) - { - std::uint64_t len{}; - return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result); - } - - case 0x7F: // UTF-8 string (indefinite length) - { - while (get() != 0xFF) - { - string_t chunk; - if (!get_cbor_string(chunk)) - { - return false; - } - result.append(chunk); - } - return true; - } - - default: - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token, "string"))); - } - } - } - - /*! - @brief reads a CBOR byte array - - This function first reads starting bytes to determine the expected - byte array length and then copies this number of bytes into the byte array. - Additionally, CBOR's byte arrays with indefinite lengths are supported. - - @param[out] result created byte array - - @return whether byte array creation completed - */ - bool get_cbor_binary(binary_t& result) - { - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary"))) - { - return false; - } - - switch (current) - { - // Binary data (0x00..0x17 bytes follow) - case 0x40: - case 0x41: - case 0x42: - case 0x43: - case 0x44: - case 0x45: - case 0x46: - case 0x47: - case 0x48: - case 0x49: - case 0x4A: - case 0x4B: - case 0x4C: - case 0x4D: - case 0x4E: - case 0x4F: - case 0x50: - case 0x51: - case 0x52: - case 0x53: - case 0x54: - case 0x55: - case 0x56: - case 0x57: - { - return get_binary(input_format_t::cbor, static_cast(current) & 0x1Fu, result); - } - - case 0x58: // Binary data (one-byte uint8_t for n follows) - { - std::uint8_t len{}; - return get_number(input_format_t::cbor, len) && - get_binary(input_format_t::cbor, len, result); - } - - case 0x59: // Binary data (two-byte uint16_t for n follow) - { - std::uint16_t len{}; - return get_number(input_format_t::cbor, len) && - get_binary(input_format_t::cbor, len, result); - } - - case 0x5A: // Binary data (four-byte uint32_t for n follow) - { - std::uint32_t len{}; - return get_number(input_format_t::cbor, len) && - get_binary(input_format_t::cbor, len, result); - } - - case 0x5B: // Binary data (eight-byte uint64_t for n follow) - { - std::uint64_t len{}; - return get_number(input_format_t::cbor, len) && - get_binary(input_format_t::cbor, len, result); - } - - case 0x5F: // Binary data (indefinite length) - { - while (get() != 0xFF) - { - binary_t chunk; - if (!get_cbor_binary(chunk)) - { - return false; - } - result.insert(result.end(), chunk.begin(), chunk.end()); - } - return true; - } - - default: - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x" + last_token, "binary"))); - } - } - } - - /*! - @param[in] len the length of the array or std::size_t(-1) for an - array of indefinite size - @param[in] tag_handler how CBOR tags should be treated - @return whether array creation completed - */ - bool get_cbor_array(const std::size_t len, - const cbor_tag_handler_t tag_handler) - { - if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len))) - { - return false; - } - - if (len != std::size_t(-1)) - { - for (std::size_t i = 0; i < len; ++i) - { - if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler))) - { - return false; - } - } - } - else - { - while (get() != 0xFF) - { - if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler))) - { - return false; - } - } - } - - return sax->end_array(); - } - - /*! - @param[in] len the length of the object or std::size_t(-1) for an - object of indefinite size - @param[in] tag_handler how CBOR tags should be treated - @return whether object creation completed - */ - bool get_cbor_object(const std::size_t len, - const cbor_tag_handler_t tag_handler) - { - if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len))) - { - return false; - } - - string_t key; - if (len != std::size_t(-1)) - { - for (std::size_t i = 0; i < len; ++i) - { - get(); - if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key))) - { - return false; - } - - if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler))) - { - return false; - } - key.clear(); - } - } - else - { - while (get() != 0xFF) - { - if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key))) - { - return false; - } - - if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler))) - { - return false; - } - key.clear(); - } - } - - return sax->end_object(); - } - - ///////////// - // MsgPack // - ///////////// - - /*! - @return whether a valid MessagePack value was passed to the SAX parser - */ - bool parse_msgpack_internal() - { - switch (get()) - { - // EOF - case std::char_traits::eof(): - return unexpect_eof(input_format_t::msgpack, "value"); - - // positive fixint - case 0x00: - case 0x01: - case 0x02: - case 0x03: - case 0x04: - case 0x05: - case 0x06: - case 0x07: - case 0x08: - case 0x09: - case 0x0A: - case 0x0B: - case 0x0C: - case 0x0D: - case 0x0E: - case 0x0F: - case 0x10: - case 0x11: - case 0x12: - case 0x13: - case 0x14: - case 0x15: - case 0x16: - case 0x17: - case 0x18: - case 0x19: - case 0x1A: - case 0x1B: - case 0x1C: - case 0x1D: - case 0x1E: - case 0x1F: - case 0x20: - case 0x21: - case 0x22: - case 0x23: - case 0x24: - case 0x25: - case 0x26: - case 0x27: - case 0x28: - case 0x29: - case 0x2A: - case 0x2B: - case 0x2C: - case 0x2D: - case 0x2E: - case 0x2F: - case 0x30: - case 0x31: - case 0x32: - case 0x33: - case 0x34: - case 0x35: - case 0x36: - case 0x37: - case 0x38: - case 0x39: - case 0x3A: - case 0x3B: - case 0x3C: - case 0x3D: - case 0x3E: - case 0x3F: - case 0x40: - case 0x41: - case 0x42: - case 0x43: - case 0x44: - case 0x45: - case 0x46: - case 0x47: - case 0x48: - case 0x49: - case 0x4A: - case 0x4B: - case 0x4C: - case 0x4D: - case 0x4E: - case 0x4F: - case 0x50: - case 0x51: - case 0x52: - case 0x53: - case 0x54: - case 0x55: - case 0x56: - case 0x57: - case 0x58: - case 0x59: - case 0x5A: - case 0x5B: - case 0x5C: - case 0x5D: - case 0x5E: - case 0x5F: - case 0x60: - case 0x61: - case 0x62: - case 0x63: - case 0x64: - case 0x65: - case 0x66: - case 0x67: - case 0x68: - case 0x69: - case 0x6A: - case 0x6B: - case 0x6C: - case 0x6D: - case 0x6E: - case 0x6F: - case 0x70: - case 0x71: - case 0x72: - case 0x73: - case 0x74: - case 0x75: - case 0x76: - case 0x77: - case 0x78: - case 0x79: - case 0x7A: - case 0x7B: - case 0x7C: - case 0x7D: - case 0x7E: - case 0x7F: - return sax->number_unsigned(static_cast(current)); - - // fixmap - case 0x80: - case 0x81: - case 0x82: - case 0x83: - case 0x84: - case 0x85: - case 0x86: - case 0x87: - case 0x88: - case 0x89: - case 0x8A: - case 0x8B: - case 0x8C: - case 0x8D: - case 0x8E: - case 0x8F: - return get_msgpack_object(static_cast(static_cast(current) & 0x0Fu)); - - // fixarray - case 0x90: - case 0x91: - case 0x92: - case 0x93: - case 0x94: - case 0x95: - case 0x96: - case 0x97: - case 0x98: - case 0x99: - case 0x9A: - case 0x9B: - case 0x9C: - case 0x9D: - case 0x9E: - case 0x9F: - return get_msgpack_array(static_cast(static_cast(current) & 0x0Fu)); - - // fixstr - case 0xA0: - case 0xA1: - case 0xA2: - case 0xA3: - case 0xA4: - case 0xA5: - case 0xA6: - case 0xA7: - case 0xA8: - case 0xA9: - case 0xAA: - case 0xAB: - case 0xAC: - case 0xAD: - case 0xAE: - case 0xAF: - case 0xB0: - case 0xB1: - case 0xB2: - case 0xB3: - case 0xB4: - case 0xB5: - case 0xB6: - case 0xB7: - case 0xB8: - case 0xB9: - case 0xBA: - case 0xBB: - case 0xBC: - case 0xBD: - case 0xBE: - case 0xBF: - case 0xD9: // str 8 - case 0xDA: // str 16 - case 0xDB: // str 32 - { - string_t s; - return get_msgpack_string(s) && sax->string(s); - } - - case 0xC0: // nil - return sax->null(); - - case 0xC2: // false - return sax->boolean(false); - - case 0xC3: // true - return sax->boolean(true); - - case 0xC4: // bin 8 - case 0xC5: // bin 16 - case 0xC6: // bin 32 - case 0xC7: // ext 8 - case 0xC8: // ext 16 - case 0xC9: // ext 32 - case 0xD4: // fixext 1 - case 0xD5: // fixext 2 - case 0xD6: // fixext 4 - case 0xD7: // fixext 8 - case 0xD8: // fixext 16 - { - binary_t b; - return get_msgpack_binary(b) && sax->binary(b); - } - - case 0xCA: // float 32 - { - float number{}; - return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast(number), ""); - } - - case 0xCB: // float 64 - { - double number{}; - return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast(number), ""); - } - - case 0xCC: // uint 8 - { - std::uint8_t number{}; - return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number); - } - - case 0xCD: // uint 16 - { - std::uint16_t number{}; - return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number); - } - - case 0xCE: // uint 32 - { - std::uint32_t number{}; - return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number); - } - - case 0xCF: // uint 64 - { - std::uint64_t number{}; - return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number); - } - - case 0xD0: // int 8 - { - std::int8_t number{}; - return get_number(input_format_t::msgpack, number) && sax->number_integer(number); - } - - case 0xD1: // int 16 - { - std::int16_t number{}; - return get_number(input_format_t::msgpack, number) && sax->number_integer(number); - } - - case 0xD2: // int 32 - { - std::int32_t number{}; - return get_number(input_format_t::msgpack, number) && sax->number_integer(number); - } - - case 0xD3: // int 64 - { - std::int64_t number{}; - return get_number(input_format_t::msgpack, number) && sax->number_integer(number); - } - - case 0xDC: // array 16 - { - std::uint16_t len{}; - return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast(len)); - } - - case 0xDD: // array 32 - { - std::uint32_t len{}; - return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast(len)); - } - - case 0xDE: // map 16 - { - std::uint16_t len{}; - return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast(len)); - } - - case 0xDF: // map 32 - { - std::uint32_t len{}; - return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast(len)); - } - - // negative fixint - case 0xE0: - case 0xE1: - case 0xE2: - case 0xE3: - case 0xE4: - case 0xE5: - case 0xE6: - case 0xE7: - case 0xE8: - case 0xE9: - case 0xEA: - case 0xEB: - case 0xEC: - case 0xED: - case 0xEE: - case 0xEF: - case 0xF0: - case 0xF1: - case 0xF2: - case 0xF3: - case 0xF4: - case 0xF5: - case 0xF6: - case 0xF7: - case 0xF8: - case 0xF9: - case 0xFA: - case 0xFB: - case 0xFC: - case 0xFD: - case 0xFE: - case 0xFF: - return sax->number_integer(static_cast(current)); - - default: // anything else - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, "invalid byte: 0x" + last_token, "value"))); - } - } - } - - /*! - @brief reads a MessagePack string - - This function first reads starting bytes to determine the expected - string length and then copies this number of bytes into a string. - - @param[out] result created string - - @return whether string creation completed - */ - bool get_msgpack_string(string_t& result) - { - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string"))) - { - return false; - } - - switch (current) - { - // fixstr - case 0xA0: - case 0xA1: - case 0xA2: - case 0xA3: - case 0xA4: - case 0xA5: - case 0xA6: - case 0xA7: - case 0xA8: - case 0xA9: - case 0xAA: - case 0xAB: - case 0xAC: - case 0xAD: - case 0xAE: - case 0xAF: - case 0xB0: - case 0xB1: - case 0xB2: - case 0xB3: - case 0xB4: - case 0xB5: - case 0xB6: - case 0xB7: - case 0xB8: - case 0xB9: - case 0xBA: - case 0xBB: - case 0xBC: - case 0xBD: - case 0xBE: - case 0xBF: - { - return get_string(input_format_t::msgpack, static_cast(current) & 0x1Fu, result); - } - - case 0xD9: // str 8 - { - std::uint8_t len{}; - return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result); - } - - case 0xDA: // str 16 - { - std::uint16_t len{}; - return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result); - } - - case 0xDB: // str 32 - { - std::uint32_t len{}; - return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result); - } - - default: - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack, "expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token, "string"))); - } - } - } - - /*! - @brief reads a MessagePack byte array - - This function first reads starting bytes to determine the expected - byte array length and then copies this number of bytes into a byte array. - - @param[out] result created byte array - - @return whether byte array creation completed - */ - bool get_msgpack_binary(binary_t& result) - { - // helper function to set the subtype - auto assign_and_return_true = [&result](std::int8_t subtype) - { - result.set_subtype(static_cast(subtype)); - return true; - }; - - switch (current) - { - case 0xC4: // bin 8 - { - std::uint8_t len{}; - return get_number(input_format_t::msgpack, len) && - get_binary(input_format_t::msgpack, len, result); - } - - case 0xC5: // bin 16 - { - std::uint16_t len{}; - return get_number(input_format_t::msgpack, len) && - get_binary(input_format_t::msgpack, len, result); - } - - case 0xC6: // bin 32 - { - std::uint32_t len{}; - return get_number(input_format_t::msgpack, len) && - get_binary(input_format_t::msgpack, len, result); - } - - case 0xC7: // ext 8 - { - std::uint8_t len{}; - std::int8_t subtype{}; - return get_number(input_format_t::msgpack, len) && - get_number(input_format_t::msgpack, subtype) && - get_binary(input_format_t::msgpack, len, result) && - assign_and_return_true(subtype); - } - - case 0xC8: // ext 16 - { - std::uint16_t len{}; - std::int8_t subtype{}; - return get_number(input_format_t::msgpack, len) && - get_number(input_format_t::msgpack, subtype) && - get_binary(input_format_t::msgpack, len, result) && - assign_and_return_true(subtype); - } - - case 0xC9: // ext 32 - { - std::uint32_t len{}; - std::int8_t subtype{}; - return get_number(input_format_t::msgpack, len) && - get_number(input_format_t::msgpack, subtype) && - get_binary(input_format_t::msgpack, len, result) && - assign_and_return_true(subtype); - } - - case 0xD4: // fixext 1 - { - std::int8_t subtype{}; - return get_number(input_format_t::msgpack, subtype) && - get_binary(input_format_t::msgpack, 1, result) && - assign_and_return_true(subtype); - } - - case 0xD5: // fixext 2 - { - std::int8_t subtype{}; - return get_number(input_format_t::msgpack, subtype) && - get_binary(input_format_t::msgpack, 2, result) && - assign_and_return_true(subtype); - } - - case 0xD6: // fixext 4 - { - std::int8_t subtype{}; - return get_number(input_format_t::msgpack, subtype) && - get_binary(input_format_t::msgpack, 4, result) && - assign_and_return_true(subtype); - } - - case 0xD7: // fixext 8 - { - std::int8_t subtype{}; - return get_number(input_format_t::msgpack, subtype) && - get_binary(input_format_t::msgpack, 8, result) && - assign_and_return_true(subtype); - } - - case 0xD8: // fixext 16 - { - std::int8_t subtype{}; - return get_number(input_format_t::msgpack, subtype) && - get_binary(input_format_t::msgpack, 16, result) && - assign_and_return_true(subtype); - } - - default: // LCOV_EXCL_LINE - return false; // LCOV_EXCL_LINE - } - } - - /*! - @param[in] len the length of the array - @return whether array creation completed - */ - bool get_msgpack_array(const std::size_t len) - { - if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len))) - { - return false; - } - - for (std::size_t i = 0; i < len; ++i) - { - if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal())) - { - return false; - } - } - - return sax->end_array(); - } - - /*! - @param[in] len the length of the object - @return whether object creation completed - */ - bool get_msgpack_object(const std::size_t len) - { - if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len))) - { - return false; - } - - string_t key; - for (std::size_t i = 0; i < len; ++i) - { - get(); - if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key))) - { - return false; - } - - if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal())) - { - return false; - } - key.clear(); - } - - return sax->end_object(); - } - - //////////// - // UBJSON // - //////////// - - /*! - @param[in] get_char whether a new character should be retrieved from the - input (true, default) or whether the last read - character should be considered instead - - @return whether a valid UBJSON value was passed to the SAX parser - */ - bool parse_ubjson_internal(const bool get_char = true) - { - return get_ubjson_value(get_char ? get_ignore_noop() : current); - } - - /*! - @brief reads a UBJSON string - - This function is either called after reading the 'S' byte explicitly - indicating a string, or in case of an object key where the 'S' byte can be - left out. - - @param[out] result created string - @param[in] get_char whether a new character should be retrieved from the - input (true, default) or whether the last read - character should be considered instead - - @return whether string creation completed - */ - bool get_ubjson_string(string_t& result, const bool get_char = true) - { - if (get_char) - { - get(); // TODO(niels): may we ignore N here? - } - - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value"))) - { - return false; - } - - switch (current) - { - case 'U': - { - std::uint8_t len{}; - return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result); - } - - case 'i': - { - std::int8_t len{}; - return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result); - } - - case 'I': - { - std::int16_t len{}; - return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result); - } - - case 'l': - { - std::int32_t len{}; - return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result); - } - - case 'L': - { - std::int64_t len{}; - return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result); - } - - default: - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string"))); - } - } - - /*! - @param[out] result determined size - @return whether size determination completed - */ - bool get_ubjson_size_value(std::size_t& result) - { - switch (get_ignore_noop()) - { - case 'U': - { - std::uint8_t number{}; - if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number))) - { - return false; - } - result = static_cast(number); - return true; - } - - case 'i': - { - std::int8_t number{}; - if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number))) - { - return false; - } - result = static_cast(number); - return true; - } - - case 'I': - { - std::int16_t number{}; - if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number))) - { - return false; - } - result = static_cast(number); - return true; - } - - case 'l': - { - std::int32_t number{}; - if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number))) - { - return false; - } - result = static_cast(number); - return true; - } - - case 'L': - { - std::int64_t number{}; - if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number))) - { - return false; - } - result = static_cast(number); - return true; - } - - default: - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size"))); - } - } - } - - /*! - @brief determine the type and size for a container - - In the optimized UBJSON format, a type and a size can be provided to allow - for a more compact representation. - - @param[out] result pair of the size and the type - - @return whether pair creation completed - */ - bool get_ubjson_size_type(std::pair& result) - { - result.first = string_t::npos; // size - result.second = 0; // type - - get_ignore_noop(); - - if (current == '$') - { - result.second = get(); // must not ignore 'N', because 'N' maybe the type - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "type"))) - { - return false; - } - - get_ignore_noop(); - if (JSON_HEDLEY_UNLIKELY(current != '#')) - { - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value"))) - { - return false; - } - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "expected '#' after type information; last byte: 0x" + last_token, "size"))); - } - - return get_ubjson_size_value(result.first); - } - - if (current == '#') - { - return get_ubjson_size_value(result.first); - } - - return true; - } - - /*! - @param prefix the previously read or set type prefix - @return whether value creation completed - */ - bool get_ubjson_value(const char_int_type prefix) - { - switch (prefix) - { - case std::char_traits::eof(): // EOF - return unexpect_eof(input_format_t::ubjson, "value"); - - case 'T': // true - return sax->boolean(true); - case 'F': // false - return sax->boolean(false); - - case 'Z': // null - return sax->null(); - - case 'U': - { - std::uint8_t number{}; - return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number); - } - - case 'i': - { - std::int8_t number{}; - return get_number(input_format_t::ubjson, number) && sax->number_integer(number); - } - - case 'I': - { - std::int16_t number{}; - return get_number(input_format_t::ubjson, number) && sax->number_integer(number); - } - - case 'l': - { - std::int32_t number{}; - return get_number(input_format_t::ubjson, number) && sax->number_integer(number); - } - - case 'L': - { - std::int64_t number{}; - return get_number(input_format_t::ubjson, number) && sax->number_integer(number); - } - - case 'd': - { - float number{}; - return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast(number), ""); - } - - case 'D': - { - double number{}; - return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast(number), ""); - } - - case 'H': - { - return get_ubjson_high_precision_number(); - } - - case 'C': // char - { - get(); - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "char"))) - { - return false; - } - if (JSON_HEDLEY_UNLIKELY(current > 127)) - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token, "char"))); - } - string_t s(1, static_cast(current)); - return sax->string(s); - } - - case 'S': // string - { - string_t s; - return get_ubjson_string(s) && sax->string(s); - } - - case '[': // array - return get_ubjson_array(); - - case '{': // object - return get_ubjson_object(); - - default: // anything else - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "invalid byte: 0x" + last_token, "value"))); - } - } - } - - /*! - @return whether array creation completed - */ - bool get_ubjson_array() - { - std::pair size_and_type; - if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type))) - { - return false; - } - - if (size_and_type.first != string_t::npos) - { - if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first))) - { - return false; - } - - if (size_and_type.second != 0) - { - if (size_and_type.second != 'N') - { - for (std::size_t i = 0; i < size_and_type.first; ++i) - { - if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second))) - { - return false; - } - } - } - } - else - { - for (std::size_t i = 0; i < size_and_type.first; ++i) - { - if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal())) - { - return false; - } - } - } - } - else - { - if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1)))) - { - return false; - } - - while (current != ']') - { - if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false))) - { - return false; - } - get_ignore_noop(); - } - } - - return sax->end_array(); - } - - /*! - @return whether object creation completed - */ - bool get_ubjson_object() - { - std::pair size_and_type; - if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type))) - { - return false; - } - - string_t key; - if (size_and_type.first != string_t::npos) - { - if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first))) - { - return false; - } - - if (size_and_type.second != 0) - { - for (std::size_t i = 0; i < size_and_type.first; ++i) - { - if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key))) - { - return false; - } - if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second))) - { - return false; - } - key.clear(); - } - } - else - { - for (std::size_t i = 0; i < size_and_type.first; ++i) - { - if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key))) - { - return false; - } - if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal())) - { - return false; - } - key.clear(); - } - } - } - else - { - if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1)))) - { - return false; - } - - while (current != '}') - { - if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key))) - { - return false; - } - if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal())) - { - return false; - } - get_ignore_noop(); - key.clear(); - } - } - - return sax->end_object(); - } - - // Note, no reader for UBJSON binary types is implemented because they do - // not exist - - bool get_ubjson_high_precision_number() - { - // get size of following number string - std::size_t size{}; - auto res = get_ubjson_size_value(size); - if (JSON_HEDLEY_UNLIKELY(!res)) - { - return res; - } - - // get number string - std::vector number_vector; - for (std::size_t i = 0; i < size; ++i) - { - get(); - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "number"))) - { - return false; - } - number_vector.push_back(static_cast(current)); - } - - // parse number string - auto number_ia = detail::input_adapter(std::forward(number_vector)); - auto number_lexer = detail::lexer(std::move(number_ia), false); - const auto result_number = number_lexer.scan(); - const auto number_string = number_lexer.get_token_string(); - const auto result_remainder = number_lexer.scan(); - - using token_type = typename detail::lexer_base::token_type; - - if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input)) - { - return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number"))); - } - - switch (result_number) - { - case token_type::value_integer: - return sax->number_integer(number_lexer.get_number_integer()); - case token_type::value_unsigned: - return sax->number_unsigned(number_lexer.get_number_unsigned()); - case token_type::value_float: - return sax->number_float(number_lexer.get_number_float(), std::move(number_string)); - default: - return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number"))); - } - } - - /////////////////////// - // Utility functions // - /////////////////////// - - /*! - @brief get next character from the input - - This function provides the interface to the used input adapter. It does - not throw in case the input reached EOF, but returns a -'ve valued - `std::char_traits::eof()` in that case. - - @return character read from the input - */ - char_int_type get() - { - ++chars_read; - return current = ia.get_character(); - } - - /*! - @return character read from the input after ignoring all 'N' entries - */ - char_int_type get_ignore_noop() - { - do - { - get(); - } - while (current == 'N'); - - return current; - } - - /* - @brief read a number from the input - - @tparam NumberType the type of the number - @param[in] format the current format (for diagnostics) - @param[out] result number of type @a NumberType - - @return whether conversion completed - - @note This function needs to respect the system's endianess, because - bytes in CBOR, MessagePack, and UBJSON are stored in network order - (big endian) and therefore need reordering on little endian systems. - */ - template - bool get_number(const input_format_t format, NumberType& result) - { - // step 1: read input into array with system's byte order - std::array vec; - for (std::size_t i = 0; i < sizeof(NumberType); ++i) - { - get(); - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number"))) - { - return false; - } - - // reverse byte order prior to conversion if necessary - if (is_little_endian != InputIsLittleEndian) - { - vec[sizeof(NumberType) - i - 1] = static_cast(current); - } - else - { - vec[i] = static_cast(current); // LCOV_EXCL_LINE - } - } - - // step 2: convert array into number of type T and return - std::memcpy(&result, vec.data(), sizeof(NumberType)); - return true; - } - - /*! - @brief create a string by reading characters from the input - - @tparam NumberType the type of the number - @param[in] format the current format (for diagnostics) - @param[in] len number of characters to read - @param[out] result string created by reading @a len bytes - - @return whether string creation completed - - @note We can not reserve @a len bytes for the result, because @a len - may be too large. Usually, @ref unexpect_eof() detects the end of - the input before we run out of string memory. - */ - template - bool get_string(const input_format_t format, - const NumberType len, - string_t& result) - { - bool success = true; - for (NumberType i = 0; i < len; i++) - { - get(); - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string"))) - { - success = false; - break; - } - result.push_back(static_cast(current)); - }; - return success; - } - - /*! - @brief create a byte array by reading bytes from the input - - @tparam NumberType the type of the number - @param[in] format the current format (for diagnostics) - @param[in] len number of bytes to read - @param[out] result byte array created by reading @a len bytes - - @return whether byte array creation completed - - @note We can not reserve @a len bytes for the result, because @a len - may be too large. Usually, @ref unexpect_eof() detects the end of - the input before we run out of memory. - */ - template - bool get_binary(const input_format_t format, - const NumberType len, - binary_t& result) - { - bool success = true; - for (NumberType i = 0; i < len; i++) - { - get(); - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary"))) - { - success = false; - break; - } - result.push_back(static_cast(current)); - } - return success; - } - - /*! - @param[in] format the current format (for diagnostics) - @param[in] context further context information (for diagnostics) - @return whether the last read character is not EOF - */ - JSON_HEDLEY_NON_NULL(3) - bool unexpect_eof(const input_format_t format, const char* context) const - { - if (JSON_HEDLEY_UNLIKELY(current == std::char_traits::eof())) - { - return sax->parse_error(chars_read, "", - parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context))); - } - return true; - } - - /*! - @return a string representation of the last read byte - */ - std::string get_token_string() const - { - std::array cr{{}}; - (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast(current)); - return std::string{cr.data()}; - } - - /*! - @param[in] format the current format - @param[in] detail a detailed error message - @param[in] context further context information - @return a message string to use in the parse_error exceptions - */ - std::string exception_message(const input_format_t format, - const std::string& detail, - const std::string& context) const - { - std::string error_msg = "syntax error while parsing "; - - switch (format) - { - case input_format_t::cbor: - error_msg += "CBOR"; - break; - - case input_format_t::msgpack: - error_msg += "MessagePack"; - break; - - case input_format_t::ubjson: - error_msg += "UBJSON"; - break; - - case input_format_t::bson: - error_msg += "BSON"; - break; - - default: // LCOV_EXCL_LINE - JSON_ASSERT(false); // LCOV_EXCL_LINE - } - - return error_msg + " " + context + ": " + detail; - } - - private: - /// input adapter - InputAdapterType ia; - - /// the current character - char_int_type current = std::char_traits::eof(); - - /// the number of characters read - std::size_t chars_read = 0; - - /// whether we can assume little endianess - const bool is_little_endian = little_endianess(); - - /// the SAX parser - json_sax_t* sax = nullptr; -}; -} // namespace detail -} // namespace nlohmann - -// #include - -// #include - -// #include - - -#include // isfinite -#include // uint8_t -#include // function -#include // string -#include // move -#include // vector - -// #include - -// #include - -// #include - -// #include - -// #include - -// #include - -// #include - - -namespace nlohmann -{ -namespace detail -{ -//////////// -// parser // -//////////// - -enum class parse_event_t : uint8_t -{ - /// the parser read `{` and started to process a JSON object - object_start, - /// the parser read `}` and finished processing a JSON object - object_end, - /// the parser read `[` and started to process a JSON array - array_start, - /// the parser read `]` and finished processing a JSON array - array_end, - /// the parser read a key of a value in an object - key, - /// the parser finished reading a JSON value - value -}; - -template -using parser_callback_t = - std::function; - -/*! -@brief syntax analysis - -This class implements a recursive descent parser. -*/ -template -class parser -{ - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using number_float_t = typename BasicJsonType::number_float_t; - using string_t = typename BasicJsonType::string_t; - using lexer_t = lexer; - using token_type = typename lexer_t::token_type; - - public: - /// a parser reading from an input adapter - explicit parser(InputAdapterType&& adapter, - const parser_callback_t cb = nullptr, - const bool allow_exceptions_ = true, - const bool skip_comments = false) - : callback(cb) - , m_lexer(std::move(adapter), skip_comments) - , allow_exceptions(allow_exceptions_) - { - // read first token - get_token(); - } - - /*! - @brief public parser interface - - @param[in] strict whether to expect the last token to be EOF - @param[in,out] result parsed JSON value - - @throw parse_error.101 in case of an unexpected token - @throw parse_error.102 if to_unicode fails or surrogate error - @throw parse_error.103 if to_unicode fails - */ - void parse(const bool strict, BasicJsonType& result) - { - if (callback) - { - json_sax_dom_callback_parser sdp(result, callback, allow_exceptions); - sax_parse_internal(&sdp); - result.assert_invariant(); - - // in strict mode, input must be completely read - if (strict && (get_token() != token_type::end_of_input)) - { - sdp.parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), - exception_message(token_type::end_of_input, "value"))); - } - - // in case of an error, return discarded value - if (sdp.is_errored()) - { - result = value_t::discarded; - return; - } - - // set top-level value to null if it was discarded by the callback - // function - if (result.is_discarded()) - { - result = nullptr; - } - } - else - { - json_sax_dom_parser sdp(result, allow_exceptions); - sax_parse_internal(&sdp); - result.assert_invariant(); - - // in strict mode, input must be completely read - if (strict && (get_token() != token_type::end_of_input)) - { - sdp.parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), - exception_message(token_type::end_of_input, "value"))); - } - - // in case of an error, return discarded value - if (sdp.is_errored()) - { - result = value_t::discarded; - return; - } - } - } - - /*! - @brief public accept interface - - @param[in] strict whether to expect the last token to be EOF - @return whether the input is a proper JSON text - */ - bool accept(const bool strict = true) - { - json_sax_acceptor sax_acceptor; - return sax_parse(&sax_acceptor, strict); - } - - template - JSON_HEDLEY_NON_NULL(2) - bool sax_parse(SAX* sax, const bool strict = true) - { - (void)detail::is_sax_static_asserts {}; - const bool result = sax_parse_internal(sax); - - // strict mode: next byte must be EOF - if (result && strict && (get_token() != token_type::end_of_input)) - { - return sax->parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), - exception_message(token_type::end_of_input, "value"))); - } - - return result; - } - - private: - template - JSON_HEDLEY_NON_NULL(2) - bool sax_parse_internal(SAX* sax) - { - // stack to remember the hierarchy of structured values we are parsing - // true = array; false = object - std::vector states; - // value to avoid a goto (see comment where set to true) - bool skip_to_state_evaluation = false; - - while (true) - { - if (!skip_to_state_evaluation) - { - // invariant: get_token() was called before each iteration - switch (last_token) - { - case token_type::begin_object: - { - if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1)))) - { - return false; - } - - // closing } -> we are done - if (get_token() == token_type::end_object) - { - if (JSON_HEDLEY_UNLIKELY(!sax->end_object())) - { - return false; - } - break; - } - - // parse key - if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string)) - { - return sax->parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), - exception_message(token_type::value_string, "object key"))); - } - if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string()))) - { - return false; - } - - // parse separator (:) - if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator)) - { - return sax->parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), - exception_message(token_type::name_separator, "object separator"))); - } - - // remember we are now inside an object - states.push_back(false); - - // parse values - get_token(); - continue; - } - - case token_type::begin_array: - { - if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1)))) - { - return false; - } - - // closing ] -> we are done - if (get_token() == token_type::end_array) - { - if (JSON_HEDLEY_UNLIKELY(!sax->end_array())) - { - return false; - } - break; - } - - // remember we are now inside an array - states.push_back(true); - - // parse values (no need to call get_token) - continue; - } - - case token_type::value_float: - { - const auto res = m_lexer.get_number_float(); - - if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res))) - { - return sax->parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'")); - } - - if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string()))) - { - return false; - } - - break; - } - - case token_type::literal_false: - { - if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false))) - { - return false; - } - break; - } - - case token_type::literal_null: - { - if (JSON_HEDLEY_UNLIKELY(!sax->null())) - { - return false; - } - break; - } - - case token_type::literal_true: - { - if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true))) - { - return false; - } - break; - } - - case token_type::value_integer: - { - if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer()))) - { - return false; - } - break; - } - - case token_type::value_string: - { - if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string()))) - { - return false; - } - break; - } - - case token_type::value_unsigned: - { - if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned()))) - { - return false; - } - break; - } - - case token_type::parse_error: - { - // using "uninitialized" to avoid "expected" message - return sax->parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), - exception_message(token_type::uninitialized, "value"))); - } - - default: // the last token was unexpected - { - return sax->parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), - exception_message(token_type::literal_or_value, "value"))); - } - } - } - else - { - skip_to_state_evaluation = false; - } - - // we reached this line after we successfully parsed a value - if (states.empty()) - { - // empty stack: we reached the end of the hierarchy: done - return true; - } - - if (states.back()) // array - { - // comma -> next value - if (get_token() == token_type::value_separator) - { - // parse a new value - get_token(); - continue; - } - - // closing ] - if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array)) - { - if (JSON_HEDLEY_UNLIKELY(!sax->end_array())) - { - return false; - } - - // We are done with this array. Before we can parse a - // new value, we need to evaluate the new state first. - // By setting skip_to_state_evaluation to false, we - // are effectively jumping to the beginning of this if. - JSON_ASSERT(!states.empty()); - states.pop_back(); - skip_to_state_evaluation = true; - continue; - } - - return sax->parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), - exception_message(token_type::end_array, "array"))); - } - else // object - { - // comma -> next value - if (get_token() == token_type::value_separator) - { - // parse key - if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string)) - { - return sax->parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), - exception_message(token_type::value_string, "object key"))); - } - - if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string()))) - { - return false; - } - - // parse separator (:) - if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator)) - { - return sax->parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), - exception_message(token_type::name_separator, "object separator"))); - } - - // parse values - get_token(); - continue; - } - - // closing } - if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object)) - { - if (JSON_HEDLEY_UNLIKELY(!sax->end_object())) - { - return false; - } - - // We are done with this object. Before we can parse a - // new value, we need to evaluate the new state first. - // By setting skip_to_state_evaluation to false, we - // are effectively jumping to the beginning of this if. - JSON_ASSERT(!states.empty()); - states.pop_back(); - skip_to_state_evaluation = true; - continue; - } - - return sax->parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), - exception_message(token_type::end_object, "object"))); - } - } - } - - /// get next token from lexer - token_type get_token() - { - return last_token = m_lexer.scan(); - } - - std::string exception_message(const token_type expected, const std::string& context) - { - std::string error_msg = "syntax error "; - - if (!context.empty()) - { - error_msg += "while parsing " + context + " "; - } - - error_msg += "- "; - - if (last_token == token_type::parse_error) - { - error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" + - m_lexer.get_token_string() + "'"; - } - else - { - error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token)); - } - - if (expected != token_type::uninitialized) - { - error_msg += "; expected " + std::string(lexer_t::token_type_name(expected)); - } - - return error_msg; - } - - private: - /// callback function - const parser_callback_t callback = nullptr; - /// the type of the last read token - token_type last_token = token_type::uninitialized; - /// the lexer - lexer_t m_lexer; - /// whether to throw exceptions in case of errors - const bool allow_exceptions = true; -}; -} // namespace detail -} // namespace nlohmann - -// #include - - -// #include - - -#include // ptrdiff_t -#include // numeric_limits - -namespace nlohmann -{ -namespace detail -{ -/* -@brief an iterator for primitive JSON types - -This class models an iterator for primitive JSON types (boolean, number, -string). It's only purpose is to allow the iterator/const_iterator classes -to "iterate" over primitive values. Internally, the iterator is modeled by -a `difference_type` variable. Value begin_value (`0`) models the begin, -end_value (`1`) models past the end. -*/ -class primitive_iterator_t -{ - private: - using difference_type = std::ptrdiff_t; - static constexpr difference_type begin_value = 0; - static constexpr difference_type end_value = begin_value + 1; - - /// iterator as signed integer type - difference_type m_it = (std::numeric_limits::min)(); - - public: - constexpr difference_type get_value() const noexcept - { - return m_it; - } - - /// set iterator to a defined beginning - void set_begin() noexcept - { - m_it = begin_value; - } - - /// set iterator to a defined past the end - void set_end() noexcept - { - m_it = end_value; - } - - /// return whether the iterator can be dereferenced - constexpr bool is_begin() const noexcept - { - return m_it == begin_value; - } - - /// return whether the iterator is at end - constexpr bool is_end() const noexcept - { - return m_it == end_value; - } - - friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept - { - return lhs.m_it == rhs.m_it; - } - - friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept - { - return lhs.m_it < rhs.m_it; - } - - primitive_iterator_t operator+(difference_type n) noexcept - { - auto result = *this; - result += n; - return result; - } - - friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept - { - return lhs.m_it - rhs.m_it; - } - - primitive_iterator_t& operator++() noexcept - { - ++m_it; - return *this; - } - - primitive_iterator_t const operator++(int) noexcept - { - auto result = *this; - ++m_it; - return result; - } - - primitive_iterator_t& operator--() noexcept - { - --m_it; - return *this; - } - - primitive_iterator_t const operator--(int) noexcept - { - auto result = *this; - --m_it; - return result; - } - - primitive_iterator_t& operator+=(difference_type n) noexcept - { - m_it += n; - return *this; - } - - primitive_iterator_t& operator-=(difference_type n) noexcept - { - m_it -= n; - return *this; - } -}; -} // namespace detail -} // namespace nlohmann - - -namespace nlohmann -{ -namespace detail -{ -/*! -@brief an iterator value - -@note This structure could easily be a union, but MSVC currently does not allow -unions members with complex constructors, see https://github.com/nlohmann/json/pull/105. -*/ -template struct internal_iterator -{ - /// iterator for JSON objects - typename BasicJsonType::object_t::iterator object_iterator {}; - /// iterator for JSON arrays - typename BasicJsonType::array_t::iterator array_iterator {}; - /// generic iterator for all other types - primitive_iterator_t primitive_iterator {}; -}; -} // namespace detail -} // namespace nlohmann - -// #include - - -#include // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next -#include // conditional, is_const, remove_const - -// #include - -// #include - -// #include - -// #include - -// #include - -// #include - -// #include - - -namespace nlohmann -{ -namespace detail -{ -// forward declare, to be able to friend it later on -template class iteration_proxy; -template class iteration_proxy_value; - -/*! -@brief a template for a bidirectional iterator for the @ref basic_json class -This class implements a both iterators (iterator and const_iterator) for the -@ref basic_json class. -@note An iterator is called *initialized* when a pointer to a JSON value has - been set (e.g., by a constructor or a copy assignment). If the iterator is - default-constructed, it is *uninitialized* and most methods are undefined. - **The library uses assertions to detect calls on uninitialized iterators.** -@requirement The class satisfies the following concept requirements: -- -[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator): - The iterator that can be moved can be moved in both directions (i.e. - incremented and decremented). -@since version 1.0.0, simplified in version 2.0.9, change to bidirectional - iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593) -*/ -template -class iter_impl -{ - /// allow basic_json to access private members - friend iter_impl::value, typename std::remove_const::type, const BasicJsonType>::type>; - friend BasicJsonType; - friend iteration_proxy; - friend iteration_proxy_value; - - using object_t = typename BasicJsonType::object_t; - using array_t = typename BasicJsonType::array_t; - // make sure BasicJsonType is basic_json or const basic_json - static_assert(is_basic_json::type>::value, - "iter_impl only accepts (const) basic_json"); - - public: - - /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17. - /// The C++ Standard has never required user-defined iterators to derive from std::iterator. - /// A user-defined iterator should provide publicly accessible typedefs named - /// iterator_category, value_type, difference_type, pointer, and reference. - /// Note that value_type is required to be non-const, even for constant iterators. - using iterator_category = std::bidirectional_iterator_tag; - - /// the type of the values when the iterator is dereferenced - using value_type = typename BasicJsonType::value_type; - /// a type to represent differences between iterators - using difference_type = typename BasicJsonType::difference_type; - /// defines a pointer to the type iterated over (value_type) - using pointer = typename std::conditional::value, - typename BasicJsonType::const_pointer, - typename BasicJsonType::pointer>::type; - /// defines a reference to the type iterated over (value_type) - using reference = - typename std::conditional::value, - typename BasicJsonType::const_reference, - typename BasicJsonType::reference>::type; - - /// default constructor - iter_impl() = default; - - /*! - @brief constructor for a given JSON instance - @param[in] object pointer to a JSON object for this iterator - @pre object != nullptr - @post The iterator is initialized; i.e. `m_object != nullptr`. - */ - explicit iter_impl(pointer object) noexcept : m_object(object) - { - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - { - m_it.object_iterator = typename object_t::iterator(); - break; - } - - case value_t::array: - { - m_it.array_iterator = typename array_t::iterator(); - break; - } - - default: - { - m_it.primitive_iterator = primitive_iterator_t(); - break; - } - } - } - - /*! - @note The conventional copy constructor and copy assignment are implicitly - defined. Combined with the following converting constructor and - assignment, they support: (1) copy from iterator to iterator, (2) - copy from const iterator to const iterator, and (3) conversion from - iterator to const iterator. However conversion from const iterator - to iterator is not defined. - */ - - /*! - @brief const copy constructor - @param[in] other const iterator to copy from - @note This copy constructor had to be defined explicitly to circumvent a bug - occurring on msvc v19.0 compiler (VS 2015) debug build. For more - information refer to: https://github.com/nlohmann/json/issues/1608 - */ - iter_impl(const iter_impl& other) noexcept - : m_object(other.m_object), m_it(other.m_it) - {} - - /*! - @brief converting assignment - @param[in] other const iterator to copy from - @return const/non-const iterator - @note It is not checked whether @a other is initialized. - */ - iter_impl& operator=(const iter_impl& other) noexcept - { - m_object = other.m_object; - m_it = other.m_it; - return *this; - } - - /*! - @brief converting constructor - @param[in] other non-const iterator to copy from - @note It is not checked whether @a other is initialized. - */ - iter_impl(const iter_impl::type>& other) noexcept - : m_object(other.m_object), m_it(other.m_it) - {} - - /*! - @brief converting assignment - @param[in] other non-const iterator to copy from - @return const/non-const iterator - @note It is not checked whether @a other is initialized. - */ - iter_impl& operator=(const iter_impl::type>& other) noexcept - { - m_object = other.m_object; - m_it = other.m_it; - return *this; - } - - private: - /*! - @brief set the iterator to the first value - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - void set_begin() noexcept - { - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - { - m_it.object_iterator = m_object->m_value.object->begin(); - break; - } - - case value_t::array: - { - m_it.array_iterator = m_object->m_value.array->begin(); - break; - } - - case value_t::null: - { - // set to end so begin()==end() is true: null is empty - m_it.primitive_iterator.set_end(); - break; - } - - default: - { - m_it.primitive_iterator.set_begin(); - break; - } - } - } - - /*! - @brief set the iterator past the last value - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - void set_end() noexcept - { - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - { - m_it.object_iterator = m_object->m_value.object->end(); - break; - } - - case value_t::array: - { - m_it.array_iterator = m_object->m_value.array->end(); - break; - } - - default: - { - m_it.primitive_iterator.set_end(); - break; - } - } - } - - public: - /*! - @brief return a reference to the value pointed to by the iterator - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - reference operator*() const - { - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - { - JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end()); - return m_it.object_iterator->second; - } - - case value_t::array: - { - JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end()); - return *m_it.array_iterator; - } - - case value_t::null: - JSON_THROW(invalid_iterator::create(214, "cannot get value")); - - default: - { - if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin())) - { - return *m_object; - } - - JSON_THROW(invalid_iterator::create(214, "cannot get value")); - } - } - } - - /*! - @brief dereference the iterator - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - pointer operator->() const - { - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - { - JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end()); - return &(m_it.object_iterator->second); - } - - case value_t::array: - { - JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end()); - return &*m_it.array_iterator; - } - - default: - { - if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin())) - { - return m_object; - } - - JSON_THROW(invalid_iterator::create(214, "cannot get value")); - } - } - } - - /*! - @brief post-increment (it++) - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - iter_impl const operator++(int) - { - auto result = *this; - ++(*this); - return result; - } - - /*! - @brief pre-increment (++it) - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - iter_impl& operator++() - { - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - { - std::advance(m_it.object_iterator, 1); - break; - } - - case value_t::array: - { - std::advance(m_it.array_iterator, 1); - break; - } - - default: - { - ++m_it.primitive_iterator; - break; - } - } - - return *this; - } - - /*! - @brief post-decrement (it--) - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - iter_impl const operator--(int) - { - auto result = *this; - --(*this); - return result; - } - - /*! - @brief pre-decrement (--it) - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - iter_impl& operator--() - { - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - { - std::advance(m_it.object_iterator, -1); - break; - } - - case value_t::array: - { - std::advance(m_it.array_iterator, -1); - break; - } - - default: - { - --m_it.primitive_iterator; - break; - } - } - - return *this; - } - - /*! - @brief comparison: equal - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - bool operator==(const iter_impl& other) const - { - // if objects are not the same, the comparison is undefined - if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object)) - { - JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers")); - } - - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - return (m_it.object_iterator == other.m_it.object_iterator); - - case value_t::array: - return (m_it.array_iterator == other.m_it.array_iterator); - - default: - return (m_it.primitive_iterator == other.m_it.primitive_iterator); - } - } - - /*! - @brief comparison: not equal - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - bool operator!=(const iter_impl& other) const - { - return !operator==(other); - } - - /*! - @brief comparison: smaller - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - bool operator<(const iter_impl& other) const - { - // if objects are not the same, the comparison is undefined - if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object)) - { - JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers")); - } - - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators")); - - case value_t::array: - return (m_it.array_iterator < other.m_it.array_iterator); - - default: - return (m_it.primitive_iterator < other.m_it.primitive_iterator); - } - } - - /*! - @brief comparison: less than or equal - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - bool operator<=(const iter_impl& other) const - { - return !other.operator < (*this); - } - - /*! - @brief comparison: greater than - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - bool operator>(const iter_impl& other) const - { - return !operator<=(other); - } - - /*! - @brief comparison: greater than or equal - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - bool operator>=(const iter_impl& other) const - { - return !operator<(other); - } - - /*! - @brief add to iterator - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - iter_impl& operator+=(difference_type i) - { - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators")); - - case value_t::array: - { - std::advance(m_it.array_iterator, i); - break; - } - - default: - { - m_it.primitive_iterator += i; - break; - } - } - - return *this; - } - - /*! - @brief subtract from iterator - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - iter_impl& operator-=(difference_type i) - { - return operator+=(-i); - } - - /*! - @brief add to iterator - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - iter_impl operator+(difference_type i) const - { - auto result = *this; - result += i; - return result; - } - - /*! - @brief addition of distance and iterator - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - friend iter_impl operator+(difference_type i, const iter_impl& it) - { - auto result = it; - result += i; - return result; - } - - /*! - @brief subtract from iterator - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - iter_impl operator-(difference_type i) const - { - auto result = *this; - result -= i; - return result; - } - - /*! - @brief return difference - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - difference_type operator-(const iter_impl& other) const - { - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators")); - - case value_t::array: - return m_it.array_iterator - other.m_it.array_iterator; - - default: - return m_it.primitive_iterator - other.m_it.primitive_iterator; - } - } - - /*! - @brief access to successor - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - reference operator[](difference_type n) const - { - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators")); - - case value_t::array: - return *std::next(m_it.array_iterator, n); - - case value_t::null: - JSON_THROW(invalid_iterator::create(214, "cannot get value")); - - default: - { - if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n)) - { - return *m_object; - } - - JSON_THROW(invalid_iterator::create(214, "cannot get value")); - } - } - } - - /*! - @brief return the key of an object iterator - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - const typename object_t::key_type& key() const - { - JSON_ASSERT(m_object != nullptr); - - if (JSON_HEDLEY_LIKELY(m_object->is_object())) - { - return m_it.object_iterator->first; - } - - JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators")); - } - - /*! - @brief return the value of an iterator - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - reference value() const - { - return operator*(); - } - - private: - /// associated JSON instance - pointer m_object = nullptr; - /// the actual iterator of the associated instance - internal_iterator::type> m_it {}; -}; -} // namespace detail -} // namespace nlohmann - -// #include - -// #include - - -#include // ptrdiff_t -#include // reverse_iterator -#include // declval - -namespace nlohmann -{ -namespace detail -{ -////////////////////// -// reverse_iterator // -////////////////////// - -/*! -@brief a template for a reverse iterator class - -@tparam Base the base iterator type to reverse. Valid types are @ref -iterator (to create @ref reverse_iterator) and @ref const_iterator (to -create @ref const_reverse_iterator). - -@requirement The class satisfies the following concept requirements: -- -[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator): - The iterator that can be moved can be moved in both directions (i.e. - incremented and decremented). -- [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator): - It is possible to write to the pointed-to element (only if @a Base is - @ref iterator). - -@since version 1.0.0 -*/ -template -class json_reverse_iterator : public std::reverse_iterator -{ - public: - using difference_type = std::ptrdiff_t; - /// shortcut to the reverse iterator adapter - using base_iterator = std::reverse_iterator; - /// the reference type for the pointed-to element - using reference = typename Base::reference; - - /// create reverse iterator from iterator - explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept - : base_iterator(it) {} - - /// create reverse iterator from base class - explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {} - - /// post-increment (it++) - json_reverse_iterator const operator++(int) - { - return static_cast(base_iterator::operator++(1)); - } - - /// pre-increment (++it) - json_reverse_iterator& operator++() - { - return static_cast(base_iterator::operator++()); - } - - /// post-decrement (it--) - json_reverse_iterator const operator--(int) - { - return static_cast(base_iterator::operator--(1)); - } - - /// pre-decrement (--it) - json_reverse_iterator& operator--() - { - return static_cast(base_iterator::operator--()); - } - - /// add to iterator - json_reverse_iterator& operator+=(difference_type i) - { - return static_cast(base_iterator::operator+=(i)); - } - - /// add to iterator - json_reverse_iterator operator+(difference_type i) const - { - return static_cast(base_iterator::operator+(i)); - } - - /// subtract from iterator - json_reverse_iterator operator-(difference_type i) const - { - return static_cast(base_iterator::operator-(i)); - } - - /// return difference - difference_type operator-(const json_reverse_iterator& other) const - { - return base_iterator(*this) - base_iterator(other); - } - - /// access to successor - reference operator[](difference_type n) const - { - return *(this->operator+(n)); - } - - /// return the key of an object iterator - auto key() const -> decltype(std::declval().key()) - { - auto it = --this->base(); - return it.key(); - } - - /// return the value of an iterator - reference value() const - { - auto it = --this->base(); - return it.operator * (); - } -}; -} // namespace detail -} // namespace nlohmann - -// #include - -// #include - - -#include // all_of -#include // isdigit -#include // max -#include // accumulate -#include // string -#include // move -#include // vector - -// #include - -// #include - -// #include - - -namespace nlohmann -{ -template -class json_pointer -{ - // allow basic_json to access private members - NLOHMANN_BASIC_JSON_TPL_DECLARATION - friend class basic_json; - - public: - /*! - @brief create JSON pointer - - Create a JSON pointer according to the syntax described in - [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3). - - @param[in] s string representing the JSON pointer; if omitted, the empty - string is assumed which references the whole JSON value - - @throw parse_error.107 if the given JSON pointer @a s is nonempty and does - not begin with a slash (`/`); see example below - - @throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s is - not followed by `0` (representing `~`) or `1` (representing `/`); see - example below - - @liveexample{The example shows the construction several valid JSON pointers - as well as the exceptional behavior.,json_pointer} - - @since version 2.0.0 - */ - explicit json_pointer(const std::string& s = "") - : reference_tokens(split(s)) - {} - - /*! - @brief return a string representation of the JSON pointer - - @invariant For each JSON pointer `ptr`, it holds: - @code {.cpp} - ptr == json_pointer(ptr.to_string()); - @endcode - - @return a string representation of the JSON pointer - - @liveexample{The example shows the result of `to_string`.,json_pointer__to_string} - - @since version 2.0.0 - */ - std::string to_string() const - { - return std::accumulate(reference_tokens.begin(), reference_tokens.end(), - std::string{}, - [](const std::string & a, const std::string & b) - { - return a + "/" + escape(b); - }); - } - - /// @copydoc to_string() - operator std::string() const - { - return to_string(); - } - - /*! - @brief append another JSON pointer at the end of this JSON pointer - - @param[in] ptr JSON pointer to append - @return JSON pointer with @a ptr appended - - @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add} - - @complexity Linear in the length of @a ptr. - - @sa @ref operator/=(std::string) to append a reference token - @sa @ref operator/=(std::size_t) to append an array index - @sa @ref operator/(const json_pointer&, const json_pointer&) for a binary operator - - @since version 3.6.0 - */ - json_pointer& operator/=(const json_pointer& ptr) - { - reference_tokens.insert(reference_tokens.end(), - ptr.reference_tokens.begin(), - ptr.reference_tokens.end()); - return *this; - } - - /*! - @brief append an unescaped reference token at the end of this JSON pointer - - @param[in] token reference token to append - @return JSON pointer with @a token appended without escaping @a token - - @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add} - - @complexity Amortized constant. - - @sa @ref operator/=(const json_pointer&) to append a JSON pointer - @sa @ref operator/=(std::size_t) to append an array index - @sa @ref operator/(const json_pointer&, std::size_t) for a binary operator - - @since version 3.6.0 - */ - json_pointer& operator/=(std::string token) - { - push_back(std::move(token)); - return *this; - } - - /*! - @brief append an array index at the end of this JSON pointer - - @param[in] array_idx array index to append - @return JSON pointer with @a array_idx appended - - @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add} - - @complexity Amortized constant. - - @sa @ref operator/=(const json_pointer&) to append a JSON pointer - @sa @ref operator/=(std::string) to append a reference token - @sa @ref operator/(const json_pointer&, std::string) for a binary operator - - @since version 3.6.0 - */ - json_pointer& operator/=(std::size_t array_idx) - { - return *this /= std::to_string(array_idx); - } - - /*! - @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer - - @param[in] lhs JSON pointer - @param[in] rhs JSON pointer - @return a new JSON pointer with @a rhs appended to @a lhs - - @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary} - - @complexity Linear in the length of @a lhs and @a rhs. - - @sa @ref operator/=(const json_pointer&) to append a JSON pointer - - @since version 3.6.0 - */ - friend json_pointer operator/(const json_pointer& lhs, - const json_pointer& rhs) - { - return json_pointer(lhs) /= rhs; - } - - /*! - @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer - - @param[in] ptr JSON pointer - @param[in] token reference token - @return a new JSON pointer with unescaped @a token appended to @a ptr - - @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary} - - @complexity Linear in the length of @a ptr. - - @sa @ref operator/=(std::string) to append a reference token - - @since version 3.6.0 - */ - friend json_pointer operator/(const json_pointer& ptr, std::string token) - { - return json_pointer(ptr) /= std::move(token); - } - - /*! - @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer - - @param[in] ptr JSON pointer - @param[in] array_idx array index - @return a new JSON pointer with @a array_idx appended to @a ptr - - @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary} - - @complexity Linear in the length of @a ptr. - - @sa @ref operator/=(std::size_t) to append an array index - - @since version 3.6.0 - */ - friend json_pointer operator/(const json_pointer& ptr, std::size_t array_idx) - { - return json_pointer(ptr) /= array_idx; - } - - /*! - @brief returns the parent of this JSON pointer - - @return parent of this JSON pointer; in case this JSON pointer is the root, - the root itself is returned - - @complexity Linear in the length of the JSON pointer. - - @liveexample{The example shows the result of `parent_pointer` for different - JSON Pointers.,json_pointer__parent_pointer} - - @since version 3.6.0 - */ - json_pointer parent_pointer() const - { - if (empty()) - { - return *this; - } - - json_pointer res = *this; - res.pop_back(); - return res; - } - - /*! - @brief remove last reference token - - @pre not `empty()` - - @liveexample{The example shows the usage of `pop_back`.,json_pointer__pop_back} - - @complexity Constant. - - @throw out_of_range.405 if JSON pointer has no parent - - @since version 3.6.0 - */ - void pop_back() - { - if (JSON_HEDLEY_UNLIKELY(empty())) - { - JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent")); - } - - reference_tokens.pop_back(); - } - - /*! - @brief return last reference token - - @pre not `empty()` - @return last reference token - - @liveexample{The example shows the usage of `back`.,json_pointer__back} - - @complexity Constant. - - @throw out_of_range.405 if JSON pointer has no parent - - @since version 3.6.0 - */ - const std::string& back() const - { - if (JSON_HEDLEY_UNLIKELY(empty())) - { - JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent")); - } - - return reference_tokens.back(); - } - - /*! - @brief append an unescaped token at the end of the reference pointer - - @param[in] token token to add - - @complexity Amortized constant. - - @liveexample{The example shows the result of `push_back` for different - JSON Pointers.,json_pointer__push_back} - - @since version 3.6.0 - */ - void push_back(const std::string& token) - { - reference_tokens.push_back(token); - } - - /// @copydoc push_back(const std::string&) - void push_back(std::string&& token) - { - reference_tokens.push_back(std::move(token)); - } - - /*! - @brief return whether pointer points to the root document - - @return true iff the JSON pointer points to the root document - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @liveexample{The example shows the result of `empty` for different JSON - Pointers.,json_pointer__empty} - - @since version 3.6.0 - */ - bool empty() const noexcept - { - return reference_tokens.empty(); - } - - private: - /*! - @param[in] s reference token to be converted into an array index - - @return integer representation of @a s - - @throw parse_error.106 if an array index begins with '0' - @throw parse_error.109 if an array index begins not with a digit - @throw out_of_range.404 if string @a s could not be converted to an integer - @throw out_of_range.410 if an array index exceeds size_type - */ - static typename BasicJsonType::size_type array_index(const std::string& s) - { - using size_type = typename BasicJsonType::size_type; - - // error condition (cf. RFC 6901, Sect. 4) - if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0')) - { - JSON_THROW(detail::parse_error::create(106, 0, - "array index '" + s + - "' must not begin with '0'")); - } - - // error condition (cf. RFC 6901, Sect. 4) - if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9'))) - { - JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number")); - } - - std::size_t processed_chars = 0; - unsigned long long res = 0; - JSON_TRY - { - res = std::stoull(s, &processed_chars); - } - JSON_CATCH(std::out_of_range&) - { - JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'")); - } - - // check if the string was completely read - if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size())) - { - JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'")); - } - - // only triggered on special platforms (like 32bit), see also - // https://github.com/nlohmann/json/pull/2203 - if (res >= static_cast((std::numeric_limits::max)())) - { - JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type")); // LCOV_EXCL_LINE - } - - return static_cast(res); - } - - json_pointer top() const - { - if (JSON_HEDLEY_UNLIKELY(empty())) - { - JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent")); - } - - json_pointer result = *this; - result.reference_tokens = {reference_tokens[0]}; - return result; - } - - /*! - @brief create and return a reference to the pointed to value - - @complexity Linear in the number of reference tokens. - - @throw parse_error.109 if array index is not a number - @throw type_error.313 if value cannot be unflattened - */ - BasicJsonType& get_and_create(BasicJsonType& j) const - { - auto result = &j; - - // in case no reference tokens exist, return a reference to the JSON value - // j which will be overwritten by a primitive value - for (const auto& reference_token : reference_tokens) - { - switch (result->type()) - { - case detail::value_t::null: - { - if (reference_token == "0") - { - // start a new array if reference token is 0 - result = &result->operator[](0); - } - else - { - // start a new object otherwise - result = &result->operator[](reference_token); - } - break; - } - - case detail::value_t::object: - { - // create an entry in the object - result = &result->operator[](reference_token); - break; - } - - case detail::value_t::array: - { - // create an entry in the array - result = &result->operator[](array_index(reference_token)); - break; - } - - /* - The following code is only reached if there exists a reference - token _and_ the current value is primitive. In this case, we have - an error situation, because primitive values may only occur as - single value; that is, with an empty list of reference tokens. - */ - default: - JSON_THROW(detail::type_error::create(313, "invalid value to unflatten")); - } - } - - return *result; - } - - /*! - @brief return a reference to the pointed to value - - @note This version does not throw if a value is not present, but tries to - create nested values instead. For instance, calling this function - with pointer `"/this/that"` on a null value is equivalent to calling - `operator[]("this").operator[]("that")` on that value, effectively - changing the null value to an object. - - @param[in] ptr a JSON value - - @return reference to the JSON value pointed to by the JSON pointer - - @complexity Linear in the length of the JSON pointer. - - @throw parse_error.106 if an array index begins with '0' - @throw parse_error.109 if an array index was not a number - @throw out_of_range.404 if the JSON pointer can not be resolved - */ - BasicJsonType& get_unchecked(BasicJsonType* ptr) const - { - for (const auto& reference_token : reference_tokens) - { - // convert null values to arrays or objects before continuing - if (ptr->is_null()) - { - // check if reference token is a number - const bool nums = - std::all_of(reference_token.begin(), reference_token.end(), - [](const unsigned char x) - { - return std::isdigit(x); - }); - - // change value to array for numbers or "-" or to object otherwise - *ptr = (nums || reference_token == "-") - ? detail::value_t::array - : detail::value_t::object; - } - - switch (ptr->type()) - { - case detail::value_t::object: - { - // use unchecked object access - ptr = &ptr->operator[](reference_token); - break; - } - - case detail::value_t::array: - { - if (reference_token == "-") - { - // explicitly treat "-" as index beyond the end - ptr = &ptr->operator[](ptr->m_value.array->size()); - } - else - { - // convert array index to number; unchecked access - ptr = &ptr->operator[](array_index(reference_token)); - } - break; - } - - default: - JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'")); - } - } - - return *ptr; - } - - /*! - @throw parse_error.106 if an array index begins with '0' - @throw parse_error.109 if an array index was not a number - @throw out_of_range.402 if the array index '-' is used - @throw out_of_range.404 if the JSON pointer can not be resolved - */ - BasicJsonType& get_checked(BasicJsonType* ptr) const - { - for (const auto& reference_token : reference_tokens) - { - switch (ptr->type()) - { - case detail::value_t::object: - { - // note: at performs range check - ptr = &ptr->at(reference_token); - break; - } - - case detail::value_t::array: - { - if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) - { - // "-" always fails the range check - JSON_THROW(detail::out_of_range::create(402, - "array index '-' (" + std::to_string(ptr->m_value.array->size()) + - ") is out of range")); - } - - // note: at performs range check - ptr = &ptr->at(array_index(reference_token)); - break; - } - - default: - JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'")); - } - } - - return *ptr; - } - - /*! - @brief return a const reference to the pointed to value - - @param[in] ptr a JSON value - - @return const reference to the JSON value pointed to by the JSON - pointer - - @throw parse_error.106 if an array index begins with '0' - @throw parse_error.109 if an array index was not a number - @throw out_of_range.402 if the array index '-' is used - @throw out_of_range.404 if the JSON pointer can not be resolved - */ - const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const - { - for (const auto& reference_token : reference_tokens) - { - switch (ptr->type()) - { - case detail::value_t::object: - { - // use unchecked object access - ptr = &ptr->operator[](reference_token); - break; - } - - case detail::value_t::array: - { - if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) - { - // "-" cannot be used for const access - JSON_THROW(detail::out_of_range::create(402, - "array index '-' (" + std::to_string(ptr->m_value.array->size()) + - ") is out of range")); - } - - // use unchecked array access - ptr = &ptr->operator[](array_index(reference_token)); - break; - } - - default: - JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'")); - } - } - - return *ptr; - } - - /*! - @throw parse_error.106 if an array index begins with '0' - @throw parse_error.109 if an array index was not a number - @throw out_of_range.402 if the array index '-' is used - @throw out_of_range.404 if the JSON pointer can not be resolved - */ - const BasicJsonType& get_checked(const BasicJsonType* ptr) const - { - for (const auto& reference_token : reference_tokens) - { - switch (ptr->type()) - { - case detail::value_t::object: - { - // note: at performs range check - ptr = &ptr->at(reference_token); - break; - } - - case detail::value_t::array: - { - if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) - { - // "-" always fails the range check - JSON_THROW(detail::out_of_range::create(402, - "array index '-' (" + std::to_string(ptr->m_value.array->size()) + - ") is out of range")); - } - - // note: at performs range check - ptr = &ptr->at(array_index(reference_token)); - break; - } - - default: - JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'")); - } - } - - return *ptr; - } - - /*! - @throw parse_error.106 if an array index begins with '0' - @throw parse_error.109 if an array index was not a number - */ - bool contains(const BasicJsonType* ptr) const - { - for (const auto& reference_token : reference_tokens) - { - switch (ptr->type()) - { - case detail::value_t::object: - { - if (!ptr->contains(reference_token)) - { - // we did not find the key in the object - return false; - } - - ptr = &ptr->operator[](reference_token); - break; - } - - case detail::value_t::array: - { - if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) - { - // "-" always fails the range check - return false; - } - if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9"))) - { - // invalid char - return false; - } - if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1)) - { - if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9'))) - { - // first char should be between '1' and '9' - return false; - } - for (std::size_t i = 1; i < reference_token.size(); i++) - { - if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9'))) - { - // other char should be between '0' and '9' - return false; - } - } - } - - const auto idx = array_index(reference_token); - if (idx >= ptr->size()) - { - // index out of range - return false; - } - - ptr = &ptr->operator[](idx); - break; - } - - default: - { - // we do not expect primitive values if there is still a - // reference token to process - return false; - } - } - } - - // no reference token left means we found a primitive value - return true; - } - - /*! - @brief split the string input to reference tokens - - @note This function is only called by the json_pointer constructor. - All exceptions below are documented there. - - @throw parse_error.107 if the pointer is not empty or begins with '/' - @throw parse_error.108 if character '~' is not followed by '0' or '1' - */ - static std::vector split(const std::string& reference_string) - { - std::vector result; - - // special case: empty reference string -> no reference tokens - if (reference_string.empty()) - { - return result; - } - - // check if nonempty reference string begins with slash - if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/')) - { - JSON_THROW(detail::parse_error::create(107, 1, - "JSON pointer must be empty or begin with '/' - was: '" + - reference_string + "'")); - } - - // extract the reference tokens: - // - slash: position of the last read slash (or end of string) - // - start: position after the previous slash - for ( - // search for the first slash after the first character - std::size_t slash = reference_string.find_first_of('/', 1), - // set the beginning of the first reference token - start = 1; - // we can stop if start == 0 (if slash == std::string::npos) - start != 0; - // set the beginning of the next reference token - // (will eventually be 0 if slash == std::string::npos) - start = (slash == std::string::npos) ? 0 : slash + 1, - // find next slash - slash = reference_string.find_first_of('/', start)) - { - // use the text between the beginning of the reference token - // (start) and the last slash (slash). - auto reference_token = reference_string.substr(start, slash - start); - - // check reference tokens are properly escaped - for (std::size_t pos = reference_token.find_first_of('~'); - pos != std::string::npos; - pos = reference_token.find_first_of('~', pos + 1)) - { - JSON_ASSERT(reference_token[pos] == '~'); - - // ~ must be followed by 0 or 1 - if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 || - (reference_token[pos + 1] != '0' && - reference_token[pos + 1] != '1'))) - { - JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'")); - } - } - - // finally, store the reference token - unescape(reference_token); - result.push_back(reference_token); - } - - return result; - } - - /*! - @brief replace all occurrences of a substring by another string - - @param[in,out] s the string to manipulate; changed so that all - occurrences of @a f are replaced with @a t - @param[in] f the substring to replace with @a t - @param[in] t the string to replace @a f - - @pre The search string @a f must not be empty. **This precondition is - enforced with an assertion.** - - @since version 2.0.0 - */ - static void replace_substring(std::string& s, const std::string& f, - const std::string& t) - { - JSON_ASSERT(!f.empty()); - for (auto pos = s.find(f); // find first occurrence of f - pos != std::string::npos; // make sure f was found - s.replace(pos, f.size(), t), // replace with t, and - pos = s.find(f, pos + t.size())) // find next occurrence of f - {} - } - - /// escape "~" to "~0" and "/" to "~1" - static std::string escape(std::string s) - { - replace_substring(s, "~", "~0"); - replace_substring(s, "/", "~1"); - return s; - } - - /// unescape "~1" to tilde and "~0" to slash (order is important!) - static void unescape(std::string& s) - { - replace_substring(s, "~1", "/"); - replace_substring(s, "~0", "~"); - } - - /*! - @param[in] reference_string the reference string to the current value - @param[in] value the value to consider - @param[in,out] result the result object to insert values to - - @note Empty objects or arrays are flattened to `null`. - */ - static void flatten(const std::string& reference_string, - const BasicJsonType& value, - BasicJsonType& result) - { - switch (value.type()) - { - case detail::value_t::array: - { - if (value.m_value.array->empty()) - { - // flatten empty array as null - result[reference_string] = nullptr; - } - else - { - // iterate array and use index as reference string - for (std::size_t i = 0; i < value.m_value.array->size(); ++i) - { - flatten(reference_string + "/" + std::to_string(i), - value.m_value.array->operator[](i), result); - } - } - break; - } - - case detail::value_t::object: - { - if (value.m_value.object->empty()) - { - // flatten empty object as null - result[reference_string] = nullptr; - } - else - { - // iterate object and use keys as reference string - for (const auto& element : *value.m_value.object) - { - flatten(reference_string + "/" + escape(element.first), element.second, result); - } - } - break; - } - - default: - { - // add primitive value with its reference string - result[reference_string] = value; - break; - } - } - } - - /*! - @param[in] value flattened JSON - - @return unflattened JSON - - @throw parse_error.109 if array index is not a number - @throw type_error.314 if value is not an object - @throw type_error.315 if object values are not primitive - @throw type_error.313 if value cannot be unflattened - */ - static BasicJsonType - unflatten(const BasicJsonType& value) - { - if (JSON_HEDLEY_UNLIKELY(!value.is_object())) - { - JSON_THROW(detail::type_error::create(314, "only objects can be unflattened")); - } - - BasicJsonType result; - - // iterate the JSON object values - for (const auto& element : *value.m_value.object) - { - if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive())) - { - JSON_THROW(detail::type_error::create(315, "values in object must be primitive")); - } - - // assign value to reference pointed to by JSON pointer; Note that if - // the JSON pointer is "" (i.e., points to the whole value), function - // get_and_create returns a reference to result itself. An assignment - // will then create a primitive value. - json_pointer(element.first).get_and_create(result) = element.second; - } - - return result; - } - - /*! - @brief compares two JSON pointers for equality - - @param[in] lhs JSON pointer to compare - @param[in] rhs JSON pointer to compare - @return whether @a lhs is equal to @a rhs - - @complexity Linear in the length of the JSON pointer - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - */ - friend bool operator==(json_pointer const& lhs, - json_pointer const& rhs) noexcept - { - return lhs.reference_tokens == rhs.reference_tokens; - } - - /*! - @brief compares two JSON pointers for inequality - - @param[in] lhs JSON pointer to compare - @param[in] rhs JSON pointer to compare - @return whether @a lhs is not equal @a rhs - - @complexity Linear in the length of the JSON pointer - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - */ - friend bool operator!=(json_pointer const& lhs, - json_pointer const& rhs) noexcept - { - return !(lhs == rhs); - } - - /// the reference tokens - std::vector reference_tokens; -}; -} // namespace nlohmann - -// #include - - -#include -#include - -// #include - - -namespace nlohmann -{ -namespace detail -{ -template -class json_ref -{ - public: - using value_type = BasicJsonType; - - json_ref(value_type&& value) - : owned_value(std::move(value)) - , value_ref(&owned_value) - , is_rvalue(true) - {} - - json_ref(const value_type& value) - : value_ref(const_cast(&value)) - , is_rvalue(false) - {} - - json_ref(std::initializer_list init) - : owned_value(init) - , value_ref(&owned_value) - , is_rvalue(true) - {} - - template < - class... Args, - enable_if_t::value, int> = 0 > - json_ref(Args && ... args) - : owned_value(std::forward(args)...) - , value_ref(&owned_value) - , is_rvalue(true) - {} - - // class should be movable only - json_ref(json_ref&&) = default; - json_ref(const json_ref&) = delete; - json_ref& operator=(const json_ref&) = delete; - json_ref& operator=(json_ref&&) = delete; - ~json_ref() = default; - - value_type moved_or_copied() const - { - if (is_rvalue) - { - return std::move(*value_ref); - } - return *value_ref; - } - - value_type const& operator*() const - { - return *static_cast(value_ref); - } - - value_type const* operator->() const - { - return static_cast(value_ref); - } - - private: - mutable value_type owned_value = nullptr; - value_type* value_ref = nullptr; - const bool is_rvalue = true; -}; -} // namespace detail -} // namespace nlohmann - -// #include - -// #include - -// #include - -// #include - - -#include // reverse -#include // array -#include // uint8_t, uint16_t, uint32_t, uint64_t -#include // memcpy -#include // numeric_limits -#include // string -#include // isnan, isinf - -// #include - -// #include - -// #include - - -#include // copy -#include // size_t -#include // streamsize -#include // back_inserter -#include // shared_ptr, make_shared -#include // basic_ostream -#include // basic_string -#include // vector -// #include - - -namespace nlohmann -{ -namespace detail -{ -/// abstract output adapter interface -template struct output_adapter_protocol -{ - virtual void write_character(CharType c) = 0; - virtual void write_characters(const CharType* s, std::size_t length) = 0; - virtual ~output_adapter_protocol() = default; -}; - -/// a type to simplify interfaces -template -using output_adapter_t = std::shared_ptr>; - -/// output adapter for byte vectors -template -class output_vector_adapter : public output_adapter_protocol -{ - public: - explicit output_vector_adapter(std::vector& vec) noexcept - : v(vec) - {} - - void write_character(CharType c) override - { - v.push_back(c); - } - - JSON_HEDLEY_NON_NULL(2) - void write_characters(const CharType* s, std::size_t length) override - { - std::copy(s, s + length, std::back_inserter(v)); - } - - private: - std::vector& v; -}; - -/// output adapter for output streams -template -class output_stream_adapter : public output_adapter_protocol -{ - public: - explicit output_stream_adapter(std::basic_ostream& s) noexcept - : stream(s) - {} - - void write_character(CharType c) override - { - stream.put(c); - } - - JSON_HEDLEY_NON_NULL(2) - void write_characters(const CharType* s, std::size_t length) override - { - stream.write(s, static_cast(length)); - } - - private: - std::basic_ostream& stream; -}; - -/// output adapter for basic_string -template> -class output_string_adapter : public output_adapter_protocol -{ - public: - explicit output_string_adapter(StringType& s) noexcept - : str(s) - {} - - void write_character(CharType c) override - { - str.push_back(c); - } - - JSON_HEDLEY_NON_NULL(2) - void write_characters(const CharType* s, std::size_t length) override - { - str.append(s, length); - } - - private: - StringType& str; -}; - -template> -class output_adapter -{ - public: - output_adapter(std::vector& vec) - : oa(std::make_shared>(vec)) {} - - output_adapter(std::basic_ostream& s) - : oa(std::make_shared>(s)) {} - - output_adapter(StringType& s) - : oa(std::make_shared>(s)) {} - - operator output_adapter_t() - { - return oa; - } - - private: - output_adapter_t oa = nullptr; -}; -} // namespace detail -} // namespace nlohmann - - -namespace nlohmann -{ -namespace detail -{ -/////////////////// -// binary writer // -/////////////////// - -/*! -@brief serialization to CBOR and MessagePack values -*/ -template -class binary_writer -{ - using string_t = typename BasicJsonType::string_t; - using binary_t = typename BasicJsonType::binary_t; - using number_float_t = typename BasicJsonType::number_float_t; - - public: - /*! - @brief create a binary writer - - @param[in] adapter output adapter to write to - */ - explicit binary_writer(output_adapter_t adapter) : oa(adapter) - { - JSON_ASSERT(oa); - } - - /*! - @param[in] j JSON value to serialize - @pre j.type() == value_t::object - */ - void write_bson(const BasicJsonType& j) - { - switch (j.type()) - { - case value_t::object: - { - write_bson_object(*j.m_value.object); - break; - } - - default: - { - JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name()))); - } - } - } - - /*! - @param[in] j JSON value to serialize - */ - void write_cbor(const BasicJsonType& j) - { - switch (j.type()) - { - case value_t::null: - { - oa->write_character(to_char_type(0xF6)); - break; - } - - case value_t::boolean: - { - oa->write_character(j.m_value.boolean - ? to_char_type(0xF5) - : to_char_type(0xF4)); - break; - } - - case value_t::number_integer: - { - if (j.m_value.number_integer >= 0) - { - // CBOR does not differentiate between positive signed - // integers and unsigned integers. Therefore, we used the - // code from the value_t::number_unsigned case here. - if (j.m_value.number_integer <= 0x17) - { - write_number(static_cast(j.m_value.number_integer)); - } - else if (j.m_value.number_integer <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x18)); - write_number(static_cast(j.m_value.number_integer)); - } - else if (j.m_value.number_integer <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x19)); - write_number(static_cast(j.m_value.number_integer)); - } - else if (j.m_value.number_integer <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x1A)); - write_number(static_cast(j.m_value.number_integer)); - } - else - { - oa->write_character(to_char_type(0x1B)); - write_number(static_cast(j.m_value.number_integer)); - } - } - else - { - // The conversions below encode the sign in the first - // byte, and the value is converted to a positive number. - const auto positive_number = -1 - j.m_value.number_integer; - if (j.m_value.number_integer >= -24) - { - write_number(static_cast(0x20 + positive_number)); - } - else if (positive_number <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x38)); - write_number(static_cast(positive_number)); - } - else if (positive_number <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x39)); - write_number(static_cast(positive_number)); - } - else if (positive_number <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x3A)); - write_number(static_cast(positive_number)); - } - else - { - oa->write_character(to_char_type(0x3B)); - write_number(static_cast(positive_number)); - } - } - break; - } - - case value_t::number_unsigned: - { - if (j.m_value.number_unsigned <= 0x17) - { - write_number(static_cast(j.m_value.number_unsigned)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x18)); - write_number(static_cast(j.m_value.number_unsigned)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x19)); - write_number(static_cast(j.m_value.number_unsigned)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x1A)); - write_number(static_cast(j.m_value.number_unsigned)); - } - else - { - oa->write_character(to_char_type(0x1B)); - write_number(static_cast(j.m_value.number_unsigned)); - } - break; - } - - case value_t::number_float: - { - if (std::isnan(j.m_value.number_float)) - { - // NaN is 0xf97e00 in CBOR - oa->write_character(to_char_type(0xF9)); - oa->write_character(to_char_type(0x7E)); - oa->write_character(to_char_type(0x00)); - } - else if (std::isinf(j.m_value.number_float)) - { - // Infinity is 0xf97c00, -Infinity is 0xf9fc00 - oa->write_character(to_char_type(0xf9)); - oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC)); - oa->write_character(to_char_type(0x00)); - } - else - { - write_compact_float(j.m_value.number_float, detail::input_format_t::cbor); - } - break; - } - - case value_t::string: - { - // step 1: write control byte and the string length - const auto N = j.m_value.string->size(); - if (N <= 0x17) - { - write_number(static_cast(0x60 + N)); - } - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x78)); - write_number(static_cast(N)); - } - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x79)); - write_number(static_cast(N)); - } - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x7A)); - write_number(static_cast(N)); - } - // LCOV_EXCL_START - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x7B)); - write_number(static_cast(N)); - } - // LCOV_EXCL_STOP - - // step 2: write the string - oa->write_characters( - reinterpret_cast(j.m_value.string->c_str()), - j.m_value.string->size()); - break; - } - - case value_t::array: - { - // step 1: write control byte and the array size - const auto N = j.m_value.array->size(); - if (N <= 0x17) - { - write_number(static_cast(0x80 + N)); - } - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x98)); - write_number(static_cast(N)); - } - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x99)); - write_number(static_cast(N)); - } - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x9A)); - write_number(static_cast(N)); - } - // LCOV_EXCL_START - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x9B)); - write_number(static_cast(N)); - } - // LCOV_EXCL_STOP - - // step 2: write each element - for (const auto& el : *j.m_value.array) - { - write_cbor(el); - } - break; - } - - case value_t::binary: - { - if (j.m_value.binary->has_subtype()) - { - write_number(static_cast(0xd8)); - write_number(j.m_value.binary->subtype()); - } - - // step 1: write control byte and the binary array size - const auto N = j.m_value.binary->size(); - if (N <= 0x17) - { - write_number(static_cast(0x40 + N)); - } - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x58)); - write_number(static_cast(N)); - } - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x59)); - write_number(static_cast(N)); - } - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x5A)); - write_number(static_cast(N)); - } - // LCOV_EXCL_START - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0x5B)); - write_number(static_cast(N)); - } - // LCOV_EXCL_STOP - - // step 2: write each element - oa->write_characters( - reinterpret_cast(j.m_value.binary->data()), - N); - - break; - } - - case value_t::object: - { - // step 1: write control byte and the object size - const auto N = j.m_value.object->size(); - if (N <= 0x17) - { - write_number(static_cast(0xA0 + N)); - } - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0xB8)); - write_number(static_cast(N)); - } - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0xB9)); - write_number(static_cast(N)); - } - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0xBA)); - write_number(static_cast(N)); - } - // LCOV_EXCL_START - else if (N <= (std::numeric_limits::max)()) - { - oa->write_character(to_char_type(0xBB)); - write_number(static_cast(N)); - } - // LCOV_EXCL_STOP - - // step 2: write each element - for (const auto& el : *j.m_value.object) - { - write_cbor(el.first); - write_cbor(el.second); - } - break; - } - - default: - break; - } - } - - /*! - @param[in] j JSON value to serialize - */ - void write_msgpack(const BasicJsonType& j) - { - switch (j.type()) - { - case value_t::null: // nil - { - oa->write_character(to_char_type(0xC0)); - break; - } - - case value_t::boolean: // true and false - { - oa->write_character(j.m_value.boolean - ? to_char_type(0xC3) - : to_char_type(0xC2)); - break; - } - - case value_t::number_integer: - { - if (j.m_value.number_integer >= 0) - { - // MessagePack does not differentiate between positive - // signed integers and unsigned integers. Therefore, we used - // the code from the value_t::number_unsigned case here. - if (j.m_value.number_unsigned < 128) - { - // positive fixnum - write_number(static_cast(j.m_value.number_integer)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) - { - // uint 8 - oa->write_character(to_char_type(0xCC)); - write_number(static_cast(j.m_value.number_integer)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) - { - // uint 16 - oa->write_character(to_char_type(0xCD)); - write_number(static_cast(j.m_value.number_integer)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) - { - // uint 32 - oa->write_character(to_char_type(0xCE)); - write_number(static_cast(j.m_value.number_integer)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) - { - // uint 64 - oa->write_character(to_char_type(0xCF)); - write_number(static_cast(j.m_value.number_integer)); - } - } - else - { - if (j.m_value.number_integer >= -32) - { - // negative fixnum - write_number(static_cast(j.m_value.number_integer)); - } - else if (j.m_value.number_integer >= (std::numeric_limits::min)() && - j.m_value.number_integer <= (std::numeric_limits::max)()) - { - // int 8 - oa->write_character(to_char_type(0xD0)); - write_number(static_cast(j.m_value.number_integer)); - } - else if (j.m_value.number_integer >= (std::numeric_limits::min)() && - j.m_value.number_integer <= (std::numeric_limits::max)()) - { - // int 16 - oa->write_character(to_char_type(0xD1)); - write_number(static_cast(j.m_value.number_integer)); - } - else if (j.m_value.number_integer >= (std::numeric_limits::min)() && - j.m_value.number_integer <= (std::numeric_limits::max)()) - { - // int 32 - oa->write_character(to_char_type(0xD2)); - write_number(static_cast(j.m_value.number_integer)); - } - else if (j.m_value.number_integer >= (std::numeric_limits::min)() && - j.m_value.number_integer <= (std::numeric_limits::max)()) - { - // int 64 - oa->write_character(to_char_type(0xD3)); - write_number(static_cast(j.m_value.number_integer)); - } - } - break; - } - - case value_t::number_unsigned: - { - if (j.m_value.number_unsigned < 128) - { - // positive fixnum - write_number(static_cast(j.m_value.number_integer)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) - { - // uint 8 - oa->write_character(to_char_type(0xCC)); - write_number(static_cast(j.m_value.number_integer)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) - { - // uint 16 - oa->write_character(to_char_type(0xCD)); - write_number(static_cast(j.m_value.number_integer)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) - { - // uint 32 - oa->write_character(to_char_type(0xCE)); - write_number(static_cast(j.m_value.number_integer)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits::max)()) - { - // uint 64 - oa->write_character(to_char_type(0xCF)); - write_number(static_cast(j.m_value.number_integer)); - } - break; - } - - case value_t::number_float: - { - write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack); - break; - } - - case value_t::string: - { - // step 1: write control byte and the string length - const auto N = j.m_value.string->size(); - if (N <= 31) - { - // fixstr - write_number(static_cast(0xA0 | N)); - } - else if (N <= (std::numeric_limits::max)()) - { - // str 8 - oa->write_character(to_char_type(0xD9)); - write_number(static_cast(N)); - } - else if (N <= (std::numeric_limits::max)()) - { - // str 16 - oa->write_character(to_char_type(0xDA)); - write_number(static_cast(N)); - } - else if (N <= (std::numeric_limits::max)()) - { - // str 32 - oa->write_character(to_char_type(0xDB)); - write_number(static_cast(N)); - } - - // step 2: write the string - oa->write_characters( - reinterpret_cast(j.m_value.string->c_str()), - j.m_value.string->size()); - break; - } - - case value_t::array: - { - // step 1: write control byte and the array size - const auto N = j.m_value.array->size(); - if (N <= 15) - { - // fixarray - write_number(static_cast(0x90 | N)); - } - else if (N <= (std::numeric_limits::max)()) - { - // array 16 - oa->write_character(to_char_type(0xDC)); - write_number(static_cast(N)); - } - else if (N <= (std::numeric_limits::max)()) - { - // array 32 - oa->write_character(to_char_type(0xDD)); - write_number(static_cast(N)); - } - - // step 2: write each element - for (const auto& el : *j.m_value.array) - { - write_msgpack(el); - } - break; - } - - case value_t::binary: - { - // step 0: determine if the binary type has a set subtype to - // determine whether or not to use the ext or fixext types - const bool use_ext = j.m_value.binary->has_subtype(); - - // step 1: write control byte and the byte string length - const auto N = j.m_value.binary->size(); - if (N <= (std::numeric_limits::max)()) - { - std::uint8_t output_type{}; - bool fixed = true; - if (use_ext) - { - switch (N) - { - case 1: - output_type = 0xD4; // fixext 1 - break; - case 2: - output_type = 0xD5; // fixext 2 - break; - case 4: - output_type = 0xD6; // fixext 4 - break; - case 8: - output_type = 0xD7; // fixext 8 - break; - case 16: - output_type = 0xD8; // fixext 16 - break; - default: - output_type = 0xC7; // ext 8 - fixed = false; - break; - } - - } - else - { - output_type = 0xC4; // bin 8 - fixed = false; - } - - oa->write_character(to_char_type(output_type)); - if (!fixed) - { - write_number(static_cast(N)); - } - } - else if (N <= (std::numeric_limits::max)()) - { - std::uint8_t output_type = use_ext - ? 0xC8 // ext 16 - : 0xC5; // bin 16 - - oa->write_character(to_char_type(output_type)); - write_number(static_cast(N)); - } - else if (N <= (std::numeric_limits::max)()) - { - std::uint8_t output_type = use_ext - ? 0xC9 // ext 32 - : 0xC6; // bin 32 - - oa->write_character(to_char_type(output_type)); - write_number(static_cast(N)); - } - - // step 1.5: if this is an ext type, write the subtype - if (use_ext) - { - write_number(static_cast(j.m_value.binary->subtype())); - } - - // step 2: write the byte string - oa->write_characters( - reinterpret_cast(j.m_value.binary->data()), - N); - - break; - } - - case value_t::object: - { - // step 1: write control byte and the object size - const auto N = j.m_value.object->size(); - if (N <= 15) - { - // fixmap - write_number(static_cast(0x80 | (N & 0xF))); - } - else if (N <= (std::numeric_limits::max)()) - { - // map 16 - oa->write_character(to_char_type(0xDE)); - write_number(static_cast(N)); - } - else if (N <= (std::numeric_limits::max)()) - { - // map 32 - oa->write_character(to_char_type(0xDF)); - write_number(static_cast(N)); - } - - // step 2: write each element - for (const auto& el : *j.m_value.object) - { - write_msgpack(el.first); - write_msgpack(el.second); - } - break; - } - - default: - break; - } - } - - /*! - @param[in] j JSON value to serialize - @param[in] use_count whether to use '#' prefixes (optimized format) - @param[in] use_type whether to use '$' prefixes (optimized format) - @param[in] add_prefix whether prefixes need to be used for this value - */ - void write_ubjson(const BasicJsonType& j, const bool use_count, - const bool use_type, const bool add_prefix = true) - { - switch (j.type()) - { - case value_t::null: - { - if (add_prefix) - { - oa->write_character(to_char_type('Z')); - } - break; - } - - case value_t::boolean: - { - if (add_prefix) - { - oa->write_character(j.m_value.boolean - ? to_char_type('T') - : to_char_type('F')); - } - break; - } - - case value_t::number_integer: - { - write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix); - break; - } - - case value_t::number_unsigned: - { - write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix); - break; - } - - case value_t::number_float: - { - write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix); - break; - } - - case value_t::string: - { - if (add_prefix) - { - oa->write_character(to_char_type('S')); - } - write_number_with_ubjson_prefix(j.m_value.string->size(), true); - oa->write_characters( - reinterpret_cast(j.m_value.string->c_str()), - j.m_value.string->size()); - break; - } - - case value_t::array: - { - if (add_prefix) - { - oa->write_character(to_char_type('[')); - } - - bool prefix_required = true; - if (use_type && !j.m_value.array->empty()) - { - JSON_ASSERT(use_count); - const CharType first_prefix = ubjson_prefix(j.front()); - const bool same_prefix = std::all_of(j.begin() + 1, j.end(), - [this, first_prefix](const BasicJsonType & v) - { - return ubjson_prefix(v) == first_prefix; - }); - - if (same_prefix) - { - prefix_required = false; - oa->write_character(to_char_type('$')); - oa->write_character(first_prefix); - } - } - - if (use_count) - { - oa->write_character(to_char_type('#')); - write_number_with_ubjson_prefix(j.m_value.array->size(), true); - } - - for (const auto& el : *j.m_value.array) - { - write_ubjson(el, use_count, use_type, prefix_required); - } - - if (!use_count) - { - oa->write_character(to_char_type(']')); - } - - break; - } - - case value_t::binary: - { - if (add_prefix) - { - oa->write_character(to_char_type('[')); - } - - if (use_type && !j.m_value.binary->empty()) - { - JSON_ASSERT(use_count); - oa->write_character(to_char_type('$')); - oa->write_character('U'); - } - - if (use_count) - { - oa->write_character(to_char_type('#')); - write_number_with_ubjson_prefix(j.m_value.binary->size(), true); - } - - if (use_type) - { - oa->write_characters( - reinterpret_cast(j.m_value.binary->data()), - j.m_value.binary->size()); - } - else - { - for (size_t i = 0; i < j.m_value.binary->size(); ++i) - { - oa->write_character(to_char_type('U')); - oa->write_character(j.m_value.binary->data()[i]); - } - } - - if (!use_count) - { - oa->write_character(to_char_type(']')); - } - - break; - } - - case value_t::object: - { - if (add_prefix) - { - oa->write_character(to_char_type('{')); - } - - bool prefix_required = true; - if (use_type && !j.m_value.object->empty()) - { - JSON_ASSERT(use_count); - const CharType first_prefix = ubjson_prefix(j.front()); - const bool same_prefix = std::all_of(j.begin(), j.end(), - [this, first_prefix](const BasicJsonType & v) - { - return ubjson_prefix(v) == first_prefix; - }); - - if (same_prefix) - { - prefix_required = false; - oa->write_character(to_char_type('$')); - oa->write_character(first_prefix); - } - } - - if (use_count) - { - oa->write_character(to_char_type('#')); - write_number_with_ubjson_prefix(j.m_value.object->size(), true); - } - - for (const auto& el : *j.m_value.object) - { - write_number_with_ubjson_prefix(el.first.size(), true); - oa->write_characters( - reinterpret_cast(el.first.c_str()), - el.first.size()); - write_ubjson(el.second, use_count, use_type, prefix_required); - } - - if (!use_count) - { - oa->write_character(to_char_type('}')); - } - - break; - } - - default: - break; - } - } - - private: - ////////// - // BSON // - ////////// - - /*! - @return The size of a BSON document entry header, including the id marker - and the entry name size (and its null-terminator). - */ - static std::size_t calc_bson_entry_header_size(const string_t& name) - { - const auto it = name.find(static_cast(0)); - if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos)) - { - JSON_THROW(out_of_range::create(409, - "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")")); - } - - return /*id*/ 1ul + name.size() + /*zero-terminator*/1u; - } - - /*! - @brief Writes the given @a element_type and @a name to the output adapter - */ - void write_bson_entry_header(const string_t& name, - const std::uint8_t element_type) - { - oa->write_character(to_char_type(element_type)); // boolean - oa->write_characters( - reinterpret_cast(name.c_str()), - name.size() + 1u); - } - - /*! - @brief Writes a BSON element with key @a name and boolean value @a value - */ - void write_bson_boolean(const string_t& name, - const bool value) - { - write_bson_entry_header(name, 0x08); - oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00)); - } - - /*! - @brief Writes a BSON element with key @a name and double value @a value - */ - void write_bson_double(const string_t& name, - const double value) - { - write_bson_entry_header(name, 0x01); - write_number(value); - } - - /*! - @return The size of the BSON-encoded string in @a value - */ - static std::size_t calc_bson_string_size(const string_t& value) - { - return sizeof(std::int32_t) + value.size() + 1ul; - } - - /*! - @brief Writes a BSON element with key @a name and string value @a value - */ - void write_bson_string(const string_t& name, - const string_t& value) - { - write_bson_entry_header(name, 0x02); - - write_number(static_cast(value.size() + 1ul)); - oa->write_characters( - reinterpret_cast(value.c_str()), - value.size() + 1); - } - - /*! - @brief Writes a BSON element with key @a name and null value - */ - void write_bson_null(const string_t& name) - { - write_bson_entry_header(name, 0x0A); - } - - /*! - @return The size of the BSON-encoded integer @a value - */ - static std::size_t calc_bson_integer_size(const std::int64_t value) - { - return (std::numeric_limits::min)() <= value && value <= (std::numeric_limits::max)() - ? sizeof(std::int32_t) - : sizeof(std::int64_t); - } - - /*! - @brief Writes a BSON element with key @a name and integer @a value - */ - void write_bson_integer(const string_t& name, - const std::int64_t value) - { - if ((std::numeric_limits::min)() <= value && value <= (std::numeric_limits::max)()) - { - write_bson_entry_header(name, 0x10); // int32 - write_number(static_cast(value)); - } - else - { - write_bson_entry_header(name, 0x12); // int64 - write_number(static_cast(value)); - } - } - - /*! - @return The size of the BSON-encoded unsigned integer in @a j - */ - static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept - { - return (value <= static_cast((std::numeric_limits::max)())) - ? sizeof(std::int32_t) - : sizeof(std::int64_t); - } - - /*! - @brief Writes a BSON element with key @a name and unsigned @a value - */ - void write_bson_unsigned(const string_t& name, - const std::uint64_t value) - { - if (value <= static_cast((std::numeric_limits::max)())) - { - write_bson_entry_header(name, 0x10 /* int32 */); - write_number(static_cast(value)); - } - else if (value <= static_cast((std::numeric_limits::max)())) - { - write_bson_entry_header(name, 0x12 /* int64 */); - write_number(static_cast(value)); - } - else - { - JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(value) + " cannot be represented by BSON as it does not fit int64")); - } - } - - /*! - @brief Writes a BSON element with key @a name and object @a value - */ - void write_bson_object_entry(const string_t& name, - const typename BasicJsonType::object_t& value) - { - write_bson_entry_header(name, 0x03); // object - write_bson_object(value); - } - - /*! - @return The size of the BSON-encoded array @a value - */ - static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value) - { - std::size_t array_index = 0ul; - - const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), std::size_t(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el) - { - return result + calc_bson_element_size(std::to_string(array_index++), el); - }); - - return sizeof(std::int32_t) + embedded_document_size + 1ul; - } - - /*! - @return The size of the BSON-encoded binary array @a value - */ - static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value) - { - return sizeof(std::int32_t) + value.size() + 1ul; - } - - /*! - @brief Writes a BSON element with key @a name and array @a value - */ - void write_bson_array(const string_t& name, - const typename BasicJsonType::array_t& value) - { - write_bson_entry_header(name, 0x04); // array - write_number(static_cast(calc_bson_array_size(value))); - - std::size_t array_index = 0ul; - - for (const auto& el : value) - { - write_bson_element(std::to_string(array_index++), el); - } - - oa->write_character(to_char_type(0x00)); - } - - /*! - @brief Writes a BSON element with key @a name and binary value @a value - */ - void write_bson_binary(const string_t& name, - const binary_t& value) - { - write_bson_entry_header(name, 0x05); - - write_number(static_cast(value.size())); - write_number(value.has_subtype() ? value.subtype() : std::uint8_t(0x00)); - - oa->write_characters(reinterpret_cast(value.data()), value.size()); - } - - /*! - @brief Calculates the size necessary to serialize the JSON value @a j with its @a name - @return The calculated size for the BSON document entry for @a j with the given @a name. - */ - static std::size_t calc_bson_element_size(const string_t& name, - const BasicJsonType& j) - { - const auto header_size = calc_bson_entry_header_size(name); - switch (j.type()) - { - case value_t::object: - return header_size + calc_bson_object_size(*j.m_value.object); - - case value_t::array: - return header_size + calc_bson_array_size(*j.m_value.array); - - case value_t::binary: - return header_size + calc_bson_binary_size(*j.m_value.binary); - - case value_t::boolean: - return header_size + 1ul; - - case value_t::number_float: - return header_size + 8ul; - - case value_t::number_integer: - return header_size + calc_bson_integer_size(j.m_value.number_integer); - - case value_t::number_unsigned: - return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned); - - case value_t::string: - return header_size + calc_bson_string_size(*j.m_value.string); - - case value_t::null: - return header_size + 0ul; - - // LCOV_EXCL_START - default: - JSON_ASSERT(false); - return 0ul; - // LCOV_EXCL_STOP - } - } - - /*! - @brief Serializes the JSON value @a j to BSON and associates it with the - key @a name. - @param name The name to associate with the JSON entity @a j within the - current BSON document - @return The size of the BSON entry - */ - void write_bson_element(const string_t& name, - const BasicJsonType& j) - { - switch (j.type()) - { - case value_t::object: - return write_bson_object_entry(name, *j.m_value.object); - - case value_t::array: - return write_bson_array(name, *j.m_value.array); - - case value_t::binary: - return write_bson_binary(name, *j.m_value.binary); - - case value_t::boolean: - return write_bson_boolean(name, j.m_value.boolean); - - case value_t::number_float: - return write_bson_double(name, j.m_value.number_float); - - case value_t::number_integer: - return write_bson_integer(name, j.m_value.number_integer); - - case value_t::number_unsigned: - return write_bson_unsigned(name, j.m_value.number_unsigned); - - case value_t::string: - return write_bson_string(name, *j.m_value.string); - - case value_t::null: - return write_bson_null(name); - - // LCOV_EXCL_START - default: - JSON_ASSERT(false); - return; - // LCOV_EXCL_STOP - } - } - - /*! - @brief Calculates the size of the BSON serialization of the given - JSON-object @a j. - @param[in] j JSON value to serialize - @pre j.type() == value_t::object - */ - static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value) - { - std::size_t document_size = std::accumulate(value.begin(), value.end(), std::size_t(0), - [](size_t result, const typename BasicJsonType::object_t::value_type & el) - { - return result += calc_bson_element_size(el.first, el.second); - }); - - return sizeof(std::int32_t) + document_size + 1ul; - } - - /*! - @param[in] j JSON value to serialize - @pre j.type() == value_t::object - */ - void write_bson_object(const typename BasicJsonType::object_t& value) - { - write_number(static_cast(calc_bson_object_size(value))); - - for (const auto& el : value) - { - write_bson_element(el.first, el.second); - } - - oa->write_character(to_char_type(0x00)); - } - - ////////// - // CBOR // - ////////// - - static constexpr CharType get_cbor_float_prefix(float /*unused*/) - { - return to_char_type(0xFA); // Single-Precision Float - } - - static constexpr CharType get_cbor_float_prefix(double /*unused*/) - { - return to_char_type(0xFB); // Double-Precision Float - } - - ///////////// - // MsgPack // - ///////////// - - static constexpr CharType get_msgpack_float_prefix(float /*unused*/) - { - return to_char_type(0xCA); // float 32 - } - - static constexpr CharType get_msgpack_float_prefix(double /*unused*/) - { - return to_char_type(0xCB); // float 64 - } - - //////////// - // UBJSON // - //////////// - - // UBJSON: write number (floating point) - template::value, int>::type = 0> - void write_number_with_ubjson_prefix(const NumberType n, - const bool add_prefix) - { - if (add_prefix) - { - oa->write_character(get_ubjson_float_prefix(n)); - } - write_number(n); - } - - // UBJSON: write number (unsigned integer) - template::value, int>::type = 0> - void write_number_with_ubjson_prefix(const NumberType n, - const bool add_prefix) - { - if (n <= static_cast((std::numeric_limits::max)())) - { - if (add_prefix) - { - oa->write_character(to_char_type('i')); // int8 - } - write_number(static_cast(n)); - } - else if (n <= (std::numeric_limits::max)()) - { - if (add_prefix) - { - oa->write_character(to_char_type('U')); // uint8 - } - write_number(static_cast(n)); - } - else if (n <= static_cast((std::numeric_limits::max)())) - { - if (add_prefix) - { - oa->write_character(to_char_type('I')); // int16 - } - write_number(static_cast(n)); - } - else if (n <= static_cast((std::numeric_limits::max)())) - { - if (add_prefix) - { - oa->write_character(to_char_type('l')); // int32 - } - write_number(static_cast(n)); - } - else if (n <= static_cast((std::numeric_limits::max)())) - { - if (add_prefix) - { - oa->write_character(to_char_type('L')); // int64 - } - write_number(static_cast(n)); - } - else - { - if (add_prefix) - { - oa->write_character(to_char_type('H')); // high-precision number - } - - const auto number = BasicJsonType(n).dump(); - write_number_with_ubjson_prefix(number.size(), true); - for (std::size_t i = 0; i < number.size(); ++i) - { - oa->write_character(to_char_type(static_cast(number[i]))); - } - } - } - - // UBJSON: write number (signed integer) - template < typename NumberType, typename std::enable_if < - std::is_signed::value&& - !std::is_floating_point::value, int >::type = 0 > - void write_number_with_ubjson_prefix(const NumberType n, - const bool add_prefix) - { - if ((std::numeric_limits::min)() <= n && n <= (std::numeric_limits::max)()) - { - if (add_prefix) - { - oa->write_character(to_char_type('i')); // int8 - } - write_number(static_cast(n)); - } - else if (static_cast((std::numeric_limits::min)()) <= n && n <= static_cast((std::numeric_limits::max)())) - { - if (add_prefix) - { - oa->write_character(to_char_type('U')); // uint8 - } - write_number(static_cast(n)); - } - else if ((std::numeric_limits::min)() <= n && n <= (std::numeric_limits::max)()) - { - if (add_prefix) - { - oa->write_character(to_char_type('I')); // int16 - } - write_number(static_cast(n)); - } - else if ((std::numeric_limits::min)() <= n && n <= (std::numeric_limits::max)()) - { - if (add_prefix) - { - oa->write_character(to_char_type('l')); // int32 - } - write_number(static_cast(n)); - } - else if ((std::numeric_limits::min)() <= n && n <= (std::numeric_limits::max)()) - { - if (add_prefix) - { - oa->write_character(to_char_type('L')); // int64 - } - write_number(static_cast(n)); - } - // LCOV_EXCL_START - else - { - if (add_prefix) - { - oa->write_character(to_char_type('H')); // high-precision number - } - - const auto number = BasicJsonType(n).dump(); - write_number_with_ubjson_prefix(number.size(), true); - for (std::size_t i = 0; i < number.size(); ++i) - { - oa->write_character(to_char_type(static_cast(number[i]))); - } - } - // LCOV_EXCL_STOP - } - - /*! - @brief determine the type prefix of container values - */ - CharType ubjson_prefix(const BasicJsonType& j) const noexcept - { - switch (j.type()) - { - case value_t::null: - return 'Z'; - - case value_t::boolean: - return j.m_value.boolean ? 'T' : 'F'; - - case value_t::number_integer: - { - if ((std::numeric_limits::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits::max)()) - { - return 'i'; - } - if ((std::numeric_limits::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits::max)()) - { - return 'U'; - } - if ((std::numeric_limits::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits::max)()) - { - return 'I'; - } - if ((std::numeric_limits::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits::max)()) - { - return 'l'; - } - if ((std::numeric_limits::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits::max)()) - { - return 'L'; - } - // anything else is treated as high-precision number - return 'H'; // LCOV_EXCL_LINE - } - - case value_t::number_unsigned: - { - if (j.m_value.number_unsigned <= static_cast((std::numeric_limits::max)())) - { - return 'i'; - } - if (j.m_value.number_unsigned <= static_cast((std::numeric_limits::max)())) - { - return 'U'; - } - if (j.m_value.number_unsigned <= static_cast((std::numeric_limits::max)())) - { - return 'I'; - } - if (j.m_value.number_unsigned <= static_cast((std::numeric_limits::max)())) - { - return 'l'; - } - if (j.m_value.number_unsigned <= static_cast((std::numeric_limits::max)())) - { - return 'L'; - } - // anything else is treated as high-precision number - return 'H'; // LCOV_EXCL_LINE - } - - case value_t::number_float: - return get_ubjson_float_prefix(j.m_value.number_float); - - case value_t::string: - return 'S'; - - case value_t::array: // fallthrough - case value_t::binary: - return '['; - - case value_t::object: - return '{'; - - default: // discarded values - return 'N'; - } - } - - static constexpr CharType get_ubjson_float_prefix(float /*unused*/) - { - return 'd'; // float 32 - } - - static constexpr CharType get_ubjson_float_prefix(double /*unused*/) - { - return 'D'; // float 64 - } - - /////////////////////// - // Utility functions // - /////////////////////// - - /* - @brief write a number to output input - @param[in] n number of type @a NumberType - @tparam NumberType the type of the number - @tparam OutputIsLittleEndian Set to true if output data is - required to be little endian - - @note This function needs to respect the system's endianess, because bytes - in CBOR, MessagePack, and UBJSON are stored in network order (big - endian) and therefore need reordering on little endian systems. - */ - template - void write_number(const NumberType n) - { - // step 1: write number to array of length NumberType - std::array vec; - std::memcpy(vec.data(), &n, sizeof(NumberType)); - - // step 2: write array to output (with possible reordering) - if (is_little_endian != OutputIsLittleEndian) - { - // reverse byte order prior to conversion if necessary - std::reverse(vec.begin(), vec.end()); - } - - oa->write_characters(vec.data(), sizeof(NumberType)); - } - - void write_compact_float(const number_float_t n, detail::input_format_t format) - { - if (static_cast(n) >= static_cast(std::numeric_limits::lowest()) && - static_cast(n) <= static_cast((std::numeric_limits::max)()) && - static_cast(static_cast(n)) == static_cast(n)) - { - oa->write_character(format == detail::input_format_t::cbor - ? get_cbor_float_prefix(static_cast(n)) - : get_msgpack_float_prefix(static_cast(n))); - write_number(static_cast(n)); - } - else - { - oa->write_character(format == detail::input_format_t::cbor - ? get_cbor_float_prefix(n) - : get_msgpack_float_prefix(n)); - write_number(n); - } - } - - public: - // The following to_char_type functions are implement the conversion - // between uint8_t and CharType. In case CharType is not unsigned, - // such a conversion is required to allow values greater than 128. - // See for a discussion. - template < typename C = CharType, - enable_if_t < std::is_signed::value && std::is_signed::value > * = nullptr > - static constexpr CharType to_char_type(std::uint8_t x) noexcept - { - return *reinterpret_cast(&x); - } - - template < typename C = CharType, - enable_if_t < std::is_signed::value && std::is_unsigned::value > * = nullptr > - static CharType to_char_type(std::uint8_t x) noexcept - { - static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t"); - static_assert(std::is_trivial::value, "CharType must be trivial"); - CharType result; - std::memcpy(&result, &x, sizeof(x)); - return result; - } - - template::value>* = nullptr> - static constexpr CharType to_char_type(std::uint8_t x) noexcept - { - return x; - } - - template < typename InputCharType, typename C = CharType, - enable_if_t < - std::is_signed::value && - std::is_signed::value && - std::is_same::type>::value - > * = nullptr > - static constexpr CharType to_char_type(InputCharType x) noexcept - { - return x; - } - - private: - /// whether we can assume little endianess - const bool is_little_endian = little_endianess(); - - /// the output - output_adapter_t oa = nullptr; -}; -} // namespace detail -} // namespace nlohmann - -// #include - -// #include - - -#include // reverse, remove, fill, find, none_of -#include // array -#include // localeconv, lconv -#include // labs, isfinite, isnan, signbit -#include // size_t, ptrdiff_t -#include // uint8_t -#include // snprintf -#include // numeric_limits -#include // string, char_traits -#include // is_same -#include // move - -// #include - - -#include // array -#include // signbit, isfinite -#include // intN_t, uintN_t -#include // memcpy, memmove -#include // numeric_limits -#include // conditional - -// #include - - -namespace nlohmann -{ -namespace detail -{ - -/*! -@brief implements the Grisu2 algorithm for binary to decimal floating-point -conversion. - -This implementation is a slightly modified version of the reference -implementation which may be obtained from -http://florian.loitsch.com/publications (bench.tar.gz). - -The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch. - -For a detailed description of the algorithm see: - -[1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with - Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming - Language Design and Implementation, PLDI 2010 -[2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately", - Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language - Design and Implementation, PLDI 1996 -*/ -namespace dtoa_impl -{ - -template -Target reinterpret_bits(const Source source) -{ - static_assert(sizeof(Target) == sizeof(Source), "size mismatch"); - - Target target; - std::memcpy(&target, &source, sizeof(Source)); - return target; -} - -struct diyfp // f * 2^e -{ - static constexpr int kPrecision = 64; // = q - - std::uint64_t f = 0; - int e = 0; - - constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {} - - /*! - @brief returns x - y - @pre x.e == y.e and x.f >= y.f - */ - static diyfp sub(const diyfp& x, const diyfp& y) noexcept - { - JSON_ASSERT(x.e == y.e); - JSON_ASSERT(x.f >= y.f); - - return {x.f - y.f, x.e}; - } - - /*! - @brief returns x * y - @note The result is rounded. (Only the upper q bits are returned.) - */ - static diyfp mul(const diyfp& x, const diyfp& y) noexcept - { - static_assert(kPrecision == 64, "internal error"); - - // Computes: - // f = round((x.f * y.f) / 2^q) - // e = x.e + y.e + q - - // Emulate the 64-bit * 64-bit multiplication: - // - // p = u * v - // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi) - // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi ) - // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 ) - // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 ) - // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3) - // = (p0_lo ) + 2^32 (Q ) + 2^64 (H ) - // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H ) - // - // (Since Q might be larger than 2^32 - 1) - // - // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H) - // - // (Q_hi + H does not overflow a 64-bit int) - // - // = p_lo + 2^64 p_hi - - const std::uint64_t u_lo = x.f & 0xFFFFFFFFu; - const std::uint64_t u_hi = x.f >> 32u; - const std::uint64_t v_lo = y.f & 0xFFFFFFFFu; - const std::uint64_t v_hi = y.f >> 32u; - - const std::uint64_t p0 = u_lo * v_lo; - const std::uint64_t p1 = u_lo * v_hi; - const std::uint64_t p2 = u_hi * v_lo; - const std::uint64_t p3 = u_hi * v_hi; - - const std::uint64_t p0_hi = p0 >> 32u; - const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu; - const std::uint64_t p1_hi = p1 >> 32u; - const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu; - const std::uint64_t p2_hi = p2 >> 32u; - - std::uint64_t Q = p0_hi + p1_lo + p2_lo; - - // The full product might now be computed as - // - // p_hi = p3 + p2_hi + p1_hi + (Q >> 32) - // p_lo = p0_lo + (Q << 32) - // - // But in this particular case here, the full p_lo is not required. - // Effectively we only need to add the highest bit in p_lo to p_hi (and - // Q_hi + 1 does not overflow). - - Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up - - const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u); - - return {h, x.e + y.e + 64}; - } - - /*! - @brief normalize x such that the significand is >= 2^(q-1) - @pre x.f != 0 - */ - static diyfp normalize(diyfp x) noexcept - { - JSON_ASSERT(x.f != 0); - - while ((x.f >> 63u) == 0) - { - x.f <<= 1u; - x.e--; - } - - return x; - } - - /*! - @brief normalize x such that the result has the exponent E - @pre e >= x.e and the upper e - x.e bits of x.f must be zero. - */ - static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept - { - const int delta = x.e - target_exponent; - - JSON_ASSERT(delta >= 0); - JSON_ASSERT(((x.f << delta) >> delta) == x.f); - - return {x.f << delta, target_exponent}; - } -}; - -struct boundaries -{ - diyfp w; - diyfp minus; - diyfp plus; -}; - -/*! -Compute the (normalized) diyfp representing the input number 'value' and its -boundaries. - -@pre value must be finite and positive -*/ -template -boundaries compute_boundaries(FloatType value) -{ - JSON_ASSERT(std::isfinite(value)); - JSON_ASSERT(value > 0); - - // Convert the IEEE representation into a diyfp. - // - // If v is denormal: - // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1)) - // If v is normalized: - // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1)) - - static_assert(std::numeric_limits::is_iec559, - "internal error: dtoa_short requires an IEEE-754 floating-point implementation"); - - constexpr int kPrecision = std::numeric_limits::digits; // = p (includes the hidden bit) - constexpr int kBias = std::numeric_limits::max_exponent - 1 + (kPrecision - 1); - constexpr int kMinExp = 1 - kBias; - constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1) - - using bits_type = typename std::conditional::type; - - const std::uint64_t bits = reinterpret_bits(value); - const std::uint64_t E = bits >> (kPrecision - 1); - const std::uint64_t F = bits & (kHiddenBit - 1); - - const bool is_denormal = E == 0; - const diyfp v = is_denormal - ? diyfp(F, kMinExp) - : diyfp(F + kHiddenBit, static_cast(E) - kBias); - - // Compute the boundaries m- and m+ of the floating-point value - // v = f * 2^e. - // - // Determine v- and v+, the floating-point predecessor and successor if v, - // respectively. - // - // v- = v - 2^e if f != 2^(p-1) or e == e_min (A) - // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B) - // - // v+ = v + 2^e - // - // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_ - // between m- and m+ round to v, regardless of how the input rounding - // algorithm breaks ties. - // - // ---+-------------+-------------+-------------+-------------+--- (A) - // v- m- v m+ v+ - // - // -----------------+------+------+-------------+-------------+--- (B) - // v- m- v m+ v+ - - const bool lower_boundary_is_closer = F == 0 && E > 1; - const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1); - const diyfp m_minus = lower_boundary_is_closer - ? diyfp(4 * v.f - 1, v.e - 2) // (B) - : diyfp(2 * v.f - 1, v.e - 1); // (A) - - // Determine the normalized w+ = m+. - const diyfp w_plus = diyfp::normalize(m_plus); - - // Determine w- = m- such that e_(w-) = e_(w+). - const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e); - - return {diyfp::normalize(v), w_minus, w_plus}; -} - -// Given normalized diyfp w, Grisu needs to find a (normalized) cached -// power-of-ten c, such that the exponent of the product c * w = f * 2^e lies -// within a certain range [alpha, gamma] (Definition 3.2 from [1]) -// -// alpha <= e = e_c + e_w + q <= gamma -// -// or -// -// f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q -// <= f_c * f_w * 2^gamma -// -// Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies -// -// 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma -// -// or -// -// 2^(q - 2 + alpha) <= c * w < 2^(q + gamma) -// -// The choice of (alpha,gamma) determines the size of the table and the form of -// the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well -// in practice: -// -// The idea is to cut the number c * w = f * 2^e into two parts, which can be -// processed independently: An integral part p1, and a fractional part p2: -// -// f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e -// = (f div 2^-e) + (f mod 2^-e) * 2^e -// = p1 + p2 * 2^e -// -// The conversion of p1 into decimal form requires a series of divisions and -// modulos by (a power of) 10. These operations are faster for 32-bit than for -// 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be -// achieved by choosing -// -// -e >= 32 or e <= -32 := gamma -// -// In order to convert the fractional part -// -// p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ... -// -// into decimal form, the fraction is repeatedly multiplied by 10 and the digits -// d[-i] are extracted in order: -// -// (10 * p2) div 2^-e = d[-1] -// (10 * p2) mod 2^-e = d[-2] / 10^1 + ... -// -// The multiplication by 10 must not overflow. It is sufficient to choose -// -// 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64. -// -// Since p2 = f mod 2^-e < 2^-e, -// -// -e <= 60 or e >= -60 := alpha - -constexpr int kAlpha = -60; -constexpr int kGamma = -32; - -struct cached_power // c = f * 2^e ~= 10^k -{ - std::uint64_t f; - int e; - int k; -}; - -/*! -For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached -power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c -satisfies (Definition 3.2 from [1]) - - alpha <= e_c + e + q <= gamma. -*/ -inline cached_power get_cached_power_for_binary_exponent(int e) -{ - // Now - // - // alpha <= e_c + e + q <= gamma (1) - // ==> f_c * 2^alpha <= c * 2^e * 2^q - // - // and since the c's are normalized, 2^(q-1) <= f_c, - // - // ==> 2^(q - 1 + alpha) <= c * 2^(e + q) - // ==> 2^(alpha - e - 1) <= c - // - // If c were an exact power of ten, i.e. c = 10^k, one may determine k as - // - // k = ceil( log_10( 2^(alpha - e - 1) ) ) - // = ceil( (alpha - e - 1) * log_10(2) ) - // - // From the paper: - // "In theory the result of the procedure could be wrong since c is rounded, - // and the computation itself is approximated [...]. In practice, however, - // this simple function is sufficient." - // - // For IEEE double precision floating-point numbers converted into - // normalized diyfp's w = f * 2^e, with q = 64, - // - // e >= -1022 (min IEEE exponent) - // -52 (p - 1) - // -52 (p - 1, possibly normalize denormal IEEE numbers) - // -11 (normalize the diyfp) - // = -1137 - // - // and - // - // e <= +1023 (max IEEE exponent) - // -52 (p - 1) - // -11 (normalize the diyfp) - // = 960 - // - // This binary exponent range [-1137,960] results in a decimal exponent - // range [-307,324]. One does not need to store a cached power for each - // k in this range. For each such k it suffices to find a cached power - // such that the exponent of the product lies in [alpha,gamma]. - // This implies that the difference of the decimal exponents of adjacent - // table entries must be less than or equal to - // - // floor( (gamma - alpha) * log_10(2) ) = 8. - // - // (A smaller distance gamma-alpha would require a larger table.) - - // NB: - // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34. - - constexpr int kCachedPowersMinDecExp = -300; - constexpr int kCachedPowersDecStep = 8; - - static constexpr std::array kCachedPowers = - { - { - { 0xAB70FE17C79AC6CA, -1060, -300 }, - { 0xFF77B1FCBEBCDC4F, -1034, -292 }, - { 0xBE5691EF416BD60C, -1007, -284 }, - { 0x8DD01FAD907FFC3C, -980, -276 }, - { 0xD3515C2831559A83, -954, -268 }, - { 0x9D71AC8FADA6C9B5, -927, -260 }, - { 0xEA9C227723EE8BCB, -901, -252 }, - { 0xAECC49914078536D, -874, -244 }, - { 0x823C12795DB6CE57, -847, -236 }, - { 0xC21094364DFB5637, -821, -228 }, - { 0x9096EA6F3848984F, -794, -220 }, - { 0xD77485CB25823AC7, -768, -212 }, - { 0xA086CFCD97BF97F4, -741, -204 }, - { 0xEF340A98172AACE5, -715, -196 }, - { 0xB23867FB2A35B28E, -688, -188 }, - { 0x84C8D4DFD2C63F3B, -661, -180 }, - { 0xC5DD44271AD3CDBA, -635, -172 }, - { 0x936B9FCEBB25C996, -608, -164 }, - { 0xDBAC6C247D62A584, -582, -156 }, - { 0xA3AB66580D5FDAF6, -555, -148 }, - { 0xF3E2F893DEC3F126, -529, -140 }, - { 0xB5B5ADA8AAFF80B8, -502, -132 }, - { 0x87625F056C7C4A8B, -475, -124 }, - { 0xC9BCFF6034C13053, -449, -116 }, - { 0x964E858C91BA2655, -422, -108 }, - { 0xDFF9772470297EBD, -396, -100 }, - { 0xA6DFBD9FB8E5B88F, -369, -92 }, - { 0xF8A95FCF88747D94, -343, -84 }, - { 0xB94470938FA89BCF, -316, -76 }, - { 0x8A08F0F8BF0F156B, -289, -68 }, - { 0xCDB02555653131B6, -263, -60 }, - { 0x993FE2C6D07B7FAC, -236, -52 }, - { 0xE45C10C42A2B3B06, -210, -44 }, - { 0xAA242499697392D3, -183, -36 }, - { 0xFD87B5F28300CA0E, -157, -28 }, - { 0xBCE5086492111AEB, -130, -20 }, - { 0x8CBCCC096F5088CC, -103, -12 }, - { 0xD1B71758E219652C, -77, -4 }, - { 0x9C40000000000000, -50, 4 }, - { 0xE8D4A51000000000, -24, 12 }, - { 0xAD78EBC5AC620000, 3, 20 }, - { 0x813F3978F8940984, 30, 28 }, - { 0xC097CE7BC90715B3, 56, 36 }, - { 0x8F7E32CE7BEA5C70, 83, 44 }, - { 0xD5D238A4ABE98068, 109, 52 }, - { 0x9F4F2726179A2245, 136, 60 }, - { 0xED63A231D4C4FB27, 162, 68 }, - { 0xB0DE65388CC8ADA8, 189, 76 }, - { 0x83C7088E1AAB65DB, 216, 84 }, - { 0xC45D1DF942711D9A, 242, 92 }, - { 0x924D692CA61BE758, 269, 100 }, - { 0xDA01EE641A708DEA, 295, 108 }, - { 0xA26DA3999AEF774A, 322, 116 }, - { 0xF209787BB47D6B85, 348, 124 }, - { 0xB454E4A179DD1877, 375, 132 }, - { 0x865B86925B9BC5C2, 402, 140 }, - { 0xC83553C5C8965D3D, 428, 148 }, - { 0x952AB45CFA97A0B3, 455, 156 }, - { 0xDE469FBD99A05FE3, 481, 164 }, - { 0xA59BC234DB398C25, 508, 172 }, - { 0xF6C69A72A3989F5C, 534, 180 }, - { 0xB7DCBF5354E9BECE, 561, 188 }, - { 0x88FCF317F22241E2, 588, 196 }, - { 0xCC20CE9BD35C78A5, 614, 204 }, - { 0x98165AF37B2153DF, 641, 212 }, - { 0xE2A0B5DC971F303A, 667, 220 }, - { 0xA8D9D1535CE3B396, 694, 228 }, - { 0xFB9B7CD9A4A7443C, 720, 236 }, - { 0xBB764C4CA7A44410, 747, 244 }, - { 0x8BAB8EEFB6409C1A, 774, 252 }, - { 0xD01FEF10A657842C, 800, 260 }, - { 0x9B10A4E5E9913129, 827, 268 }, - { 0xE7109BFBA19C0C9D, 853, 276 }, - { 0xAC2820D9623BF429, 880, 284 }, - { 0x80444B5E7AA7CF85, 907, 292 }, - { 0xBF21E44003ACDD2D, 933, 300 }, - { 0x8E679C2F5E44FF8F, 960, 308 }, - { 0xD433179D9C8CB841, 986, 316 }, - { 0x9E19DB92B4E31BA9, 1013, 324 }, - } - }; - - // This computation gives exactly the same results for k as - // k = ceil((kAlpha - e - 1) * 0.30102999566398114) - // for |e| <= 1500, but doesn't require floating-point operations. - // NB: log_10(2) ~= 78913 / 2^18 - JSON_ASSERT(e >= -1500); - JSON_ASSERT(e <= 1500); - const int f = kAlpha - e - 1; - const int k = (f * 78913) / (1 << 18) + static_cast(f > 0); - - const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep; - JSON_ASSERT(index >= 0); - JSON_ASSERT(static_cast(index) < kCachedPowers.size()); - - const cached_power cached = kCachedPowers[static_cast(index)]; - JSON_ASSERT(kAlpha <= cached.e + e + 64); - JSON_ASSERT(kGamma >= cached.e + e + 64); - - return cached; -} - -/*! -For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k. -For n == 0, returns 1 and sets pow10 := 1. -*/ -inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10) -{ - // LCOV_EXCL_START - if (n >= 1000000000) - { - pow10 = 1000000000; - return 10; - } - // LCOV_EXCL_STOP - else if (n >= 100000000) - { - pow10 = 100000000; - return 9; - } - else if (n >= 10000000) - { - pow10 = 10000000; - return 8; - } - else if (n >= 1000000) - { - pow10 = 1000000; - return 7; - } - else if (n >= 100000) - { - pow10 = 100000; - return 6; - } - else if (n >= 10000) - { - pow10 = 10000; - return 5; - } - else if (n >= 1000) - { - pow10 = 1000; - return 4; - } - else if (n >= 100) - { - pow10 = 100; - return 3; - } - else if (n >= 10) - { - pow10 = 10; - return 2; - } - else - { - pow10 = 1; - return 1; - } -} - -inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta, - std::uint64_t rest, std::uint64_t ten_k) -{ - JSON_ASSERT(len >= 1); - JSON_ASSERT(dist <= delta); - JSON_ASSERT(rest <= delta); - JSON_ASSERT(ten_k > 0); - - // <--------------------------- delta ----> - // <---- dist ---------> - // --------------[------------------+-------------------]-------------- - // M- w M+ - // - // ten_k - // <------> - // <---- rest ----> - // --------------[------------------+----+--------------]-------------- - // w V - // = buf * 10^k - // - // ten_k represents a unit-in-the-last-place in the decimal representation - // stored in buf. - // Decrement buf by ten_k while this takes buf closer to w. - - // The tests are written in this order to avoid overflow in unsigned - // integer arithmetic. - - while (rest < dist - && delta - rest >= ten_k - && (rest + ten_k < dist || dist - rest > rest + ten_k - dist)) - { - JSON_ASSERT(buf[len - 1] != '0'); - buf[len - 1]--; - rest += ten_k; - } -} - -/*! -Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+. -M- and M+ must be normalized and share the same exponent -60 <= e <= -32. -*/ -inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent, - diyfp M_minus, diyfp w, diyfp M_plus) -{ - static_assert(kAlpha >= -60, "internal error"); - static_assert(kGamma <= -32, "internal error"); - - // Generates the digits (and the exponent) of a decimal floating-point - // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's - // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma. - // - // <--------------------------- delta ----> - // <---- dist ---------> - // --------------[------------------+-------------------]-------------- - // M- w M+ - // - // Grisu2 generates the digits of M+ from left to right and stops as soon as - // V is in [M-,M+]. - - JSON_ASSERT(M_plus.e >= kAlpha); - JSON_ASSERT(M_plus.e <= kGamma); - - std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e) - std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e) - - // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0): - // - // M+ = f * 2^e - // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e - // = ((p1 ) * 2^-e + (p2 )) * 2^e - // = p1 + p2 * 2^e - - const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e); - - auto p1 = static_cast(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.) - std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e - - // 1) - // - // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0] - - JSON_ASSERT(p1 > 0); - - std::uint32_t pow10; - const int k = find_largest_pow10(p1, pow10); - - // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1) - // - // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1)) - // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1)) - // - // M+ = p1 + p2 * 2^e - // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e - // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e - // = d[k-1] * 10^(k-1) + ( rest) * 2^e - // - // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0) - // - // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0] - // - // but stop as soon as - // - // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e - - int n = k; - while (n > 0) - { - // Invariants: - // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k) - // pow10 = 10^(n-1) <= p1 < 10^n - // - const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1) - const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1) - // - // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e - // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e) - // - JSON_ASSERT(d <= 9); - buffer[length++] = static_cast('0' + d); // buffer := buffer * 10 + d - // - // M+ = buffer * 10^(n-1) + (r + p2 * 2^e) - // - p1 = r; - n--; - // - // M+ = buffer * 10^n + (p1 + p2 * 2^e) - // pow10 = 10^n - // - - // Now check if enough digits have been generated. - // Compute - // - // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e - // - // Note: - // Since rest and delta share the same exponent e, it suffices to - // compare the significands. - const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2; - if (rest <= delta) - { - // V = buffer * 10^n, with M- <= V <= M+. - - decimal_exponent += n; - - // We may now just stop. But instead look if the buffer could be - // decremented to bring V closer to w. - // - // pow10 = 10^n is now 1 ulp in the decimal representation V. - // The rounding procedure works with diyfp's with an implicit - // exponent of e. - // - // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e - // - const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e; - grisu2_round(buffer, length, dist, delta, rest, ten_n); - - return; - } - - pow10 /= 10; - // - // pow10 = 10^(n-1) <= p1 < 10^n - // Invariants restored. - } - - // 2) - // - // The digits of the integral part have been generated: - // - // M+ = d[k-1]...d[1]d[0] + p2 * 2^e - // = buffer + p2 * 2^e - // - // Now generate the digits of the fractional part p2 * 2^e. - // - // Note: - // No decimal point is generated: the exponent is adjusted instead. - // - // p2 actually represents the fraction - // - // p2 * 2^e - // = p2 / 2^-e - // = d[-1] / 10^1 + d[-2] / 10^2 + ... - // - // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...) - // - // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m - // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...) - // - // using - // - // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e) - // = ( d) * 2^-e + ( r) - // - // or - // 10^m * p2 * 2^e = d + r * 2^e - // - // i.e. - // - // M+ = buffer + p2 * 2^e - // = buffer + 10^-m * (d + r * 2^e) - // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e - // - // and stop as soon as 10^-m * r * 2^e <= delta * 2^e - - JSON_ASSERT(p2 > delta); - - int m = 0; - for (;;) - { - // Invariant: - // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e - // = buffer * 10^-m + 10^-m * (p2 ) * 2^e - // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e - // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e - // - JSON_ASSERT(p2 <= (std::numeric_limits::max)() / 10); - p2 *= 10; - const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e - const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e - // - // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e - // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e)) - // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e - // - JSON_ASSERT(d <= 9); - buffer[length++] = static_cast('0' + d); // buffer := buffer * 10 + d - // - // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e - // - p2 = r; - m++; - // - // M+ = buffer * 10^-m + 10^-m * p2 * 2^e - // Invariant restored. - - // Check if enough digits have been generated. - // - // 10^-m * p2 * 2^e <= delta * 2^e - // p2 * 2^e <= 10^m * delta * 2^e - // p2 <= 10^m * delta - delta *= 10; - dist *= 10; - if (p2 <= delta) - { - break; - } - } - - // V = buffer * 10^-m, with M- <= V <= M+. - - decimal_exponent -= m; - - // 1 ulp in the decimal representation is now 10^-m. - // Since delta and dist are now scaled by 10^m, we need to do the - // same with ulp in order to keep the units in sync. - // - // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e - // - const std::uint64_t ten_m = one.f; - grisu2_round(buffer, length, dist, delta, p2, ten_m); - - // By construction this algorithm generates the shortest possible decimal - // number (Loitsch, Theorem 6.2) which rounds back to w. - // For an input number of precision p, at least - // - // N = 1 + ceil(p * log_10(2)) - // - // decimal digits are sufficient to identify all binary floating-point - // numbers (Matula, "In-and-Out conversions"). - // This implies that the algorithm does not produce more than N decimal - // digits. - // - // N = 17 for p = 53 (IEEE double precision) - // N = 9 for p = 24 (IEEE single precision) -} - -/*! -v = buf * 10^decimal_exponent -len is the length of the buffer (number of decimal digits) -The buffer must be large enough, i.e. >= max_digits10. -*/ -JSON_HEDLEY_NON_NULL(1) -inline void grisu2(char* buf, int& len, int& decimal_exponent, - diyfp m_minus, diyfp v, diyfp m_plus) -{ - JSON_ASSERT(m_plus.e == m_minus.e); - JSON_ASSERT(m_plus.e == v.e); - - // --------(-----------------------+-----------------------)-------- (A) - // m- v m+ - // - // --------------------(-----------+-----------------------)-------- (B) - // m- v m+ - // - // First scale v (and m- and m+) such that the exponent is in the range - // [alpha, gamma]. - - const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e); - - const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k - - // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma] - const diyfp w = diyfp::mul(v, c_minus_k); - const diyfp w_minus = diyfp::mul(m_minus, c_minus_k); - const diyfp w_plus = diyfp::mul(m_plus, c_minus_k); - - // ----(---+---)---------------(---+---)---------------(---+---)---- - // w- w w+ - // = c*m- = c*v = c*m+ - // - // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and - // w+ are now off by a small amount. - // In fact: - // - // w - v * 10^k < 1 ulp - // - // To account for this inaccuracy, add resp. subtract 1 ulp. - // - // --------+---[---------------(---+---)---------------]---+-------- - // w- M- w M+ w+ - // - // Now any number in [M-, M+] (bounds included) will round to w when input, - // regardless of how the input rounding algorithm breaks ties. - // - // And digit_gen generates the shortest possible such number in [M-, M+]. - // Note that this does not mean that Grisu2 always generates the shortest - // possible number in the interval (m-, m+). - const diyfp M_minus(w_minus.f + 1, w_minus.e); - const diyfp M_plus (w_plus.f - 1, w_plus.e ); - - decimal_exponent = -cached.k; // = -(-k) = k - - grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus); -} - -/*! -v = buf * 10^decimal_exponent -len is the length of the buffer (number of decimal digits) -The buffer must be large enough, i.e. >= max_digits10. -*/ -template -JSON_HEDLEY_NON_NULL(1) -void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value) -{ - static_assert(diyfp::kPrecision >= std::numeric_limits::digits + 3, - "internal error: not enough precision"); - - JSON_ASSERT(std::isfinite(value)); - JSON_ASSERT(value > 0); - - // If the neighbors (and boundaries) of 'value' are always computed for double-precision - // numbers, all float's can be recovered using strtod (and strtof). However, the resulting - // decimal representations are not exactly "short". - // - // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars) - // says "value is converted to a string as if by std::sprintf in the default ("C") locale" - // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars' - // does. - // On the other hand, the documentation for 'std::to_chars' requires that "parsing the - // representation using the corresponding std::from_chars function recovers value exactly". That - // indicates that single precision floating-point numbers should be recovered using - // 'std::strtof'. - // - // NB: If the neighbors are computed for single-precision numbers, there is a single float - // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision - // value is off by 1 ulp. -#if 0 - const boundaries w = compute_boundaries(static_cast(value)); -#else - const boundaries w = compute_boundaries(value); -#endif - - grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus); -} - -/*! -@brief appends a decimal representation of e to buf -@return a pointer to the element following the exponent. -@pre -1000 < e < 1000 -*/ -JSON_HEDLEY_NON_NULL(1) -JSON_HEDLEY_RETURNS_NON_NULL -inline char* append_exponent(char* buf, int e) -{ - JSON_ASSERT(e > -1000); - JSON_ASSERT(e < 1000); - - if (e < 0) - { - e = -e; - *buf++ = '-'; - } - else - { - *buf++ = '+'; - } - - auto k = static_cast(e); - if (k < 10) - { - // Always print at least two digits in the exponent. - // This is for compatibility with printf("%g"). - *buf++ = '0'; - *buf++ = static_cast('0' + k); - } - else if (k < 100) - { - *buf++ = static_cast('0' + k / 10); - k %= 10; - *buf++ = static_cast('0' + k); - } - else - { - *buf++ = static_cast('0' + k / 100); - k %= 100; - *buf++ = static_cast('0' + k / 10); - k %= 10; - *buf++ = static_cast('0' + k); - } - - return buf; -} - -/*! -@brief prettify v = buf * 10^decimal_exponent - -If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point -notation. Otherwise it will be printed in exponential notation. - -@pre min_exp < 0 -@pre max_exp > 0 -*/ -JSON_HEDLEY_NON_NULL(1) -JSON_HEDLEY_RETURNS_NON_NULL -inline char* format_buffer(char* buf, int len, int decimal_exponent, - int min_exp, int max_exp) -{ - JSON_ASSERT(min_exp < 0); - JSON_ASSERT(max_exp > 0); - - const int k = len; - const int n = len + decimal_exponent; - - // v = buf * 10^(n-k) - // k is the length of the buffer (number of decimal digits) - // n is the position of the decimal point relative to the start of the buffer. - - if (k <= n && n <= max_exp) - { - // digits[000] - // len <= max_exp + 2 - - std::memset(buf + k, '0', static_cast(n) - static_cast(k)); - // Make it look like a floating-point number (#362, #378) - buf[n + 0] = '.'; - buf[n + 1] = '0'; - return buf + (static_cast(n) + 2); - } - - if (0 < n && n <= max_exp) - { - // dig.its - // len <= max_digits10 + 1 - - JSON_ASSERT(k > n); - - std::memmove(buf + (static_cast(n) + 1), buf + n, static_cast(k) - static_cast(n)); - buf[n] = '.'; - return buf + (static_cast(k) + 1U); - } - - if (min_exp < n && n <= 0) - { - // 0.[000]digits - // len <= 2 + (-min_exp - 1) + max_digits10 - - std::memmove(buf + (2 + static_cast(-n)), buf, static_cast(k)); - buf[0] = '0'; - buf[1] = '.'; - std::memset(buf + 2, '0', static_cast(-n)); - return buf + (2U + static_cast(-n) + static_cast(k)); - } - - if (k == 1) - { - // dE+123 - // len <= 1 + 5 - - buf += 1; - } - else - { - // d.igitsE+123 - // len <= max_digits10 + 1 + 5 - - std::memmove(buf + 2, buf + 1, static_cast(k) - 1); - buf[1] = '.'; - buf += 1 + static_cast(k); - } - - *buf++ = 'e'; - return append_exponent(buf, n - 1); -} - -} // namespace dtoa_impl - -/*! -@brief generates a decimal representation of the floating-point number value in [first, last). - -The format of the resulting decimal representation is similar to printf's %g -format. Returns an iterator pointing past-the-end of the decimal representation. - -@note The input number must be finite, i.e. NaN's and Inf's are not supported. -@note The buffer must be large enough. -@note The result is NOT null-terminated. -*/ -template -JSON_HEDLEY_NON_NULL(1, 2) -JSON_HEDLEY_RETURNS_NON_NULL -char* to_chars(char* first, const char* last, FloatType value) -{ - static_cast(last); // maybe unused - fix warning - JSON_ASSERT(std::isfinite(value)); - - // Use signbit(value) instead of (value < 0) since signbit works for -0. - if (std::signbit(value)) - { - value = -value; - *first++ = '-'; - } - - if (value == 0) // +-0 - { - *first++ = '0'; - // Make it look like a floating-point number (#362, #378) - *first++ = '.'; - *first++ = '0'; - return first; - } - - JSON_ASSERT(last - first >= std::numeric_limits::max_digits10); - - // Compute v = buffer * 10^decimal_exponent. - // The decimal digits are stored in the buffer, which needs to be interpreted - // as an unsigned decimal integer. - // len is the length of the buffer, i.e. the number of decimal digits. - int len = 0; - int decimal_exponent = 0; - dtoa_impl::grisu2(first, len, decimal_exponent, value); - - JSON_ASSERT(len <= std::numeric_limits::max_digits10); - - // Format the buffer like printf("%.*g", prec, value) - constexpr int kMinExp = -4; - // Use digits10 here to increase compatibility with version 2. - constexpr int kMaxExp = std::numeric_limits::digits10; - - JSON_ASSERT(last - first >= kMaxExp + 2); - JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits::max_digits10); - JSON_ASSERT(last - first >= std::numeric_limits::max_digits10 + 6); - - return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp); -} - -} // namespace detail -} // namespace nlohmann - -// #include - -// #include - -// #include - -// #include - -// #include - -// #include - - -namespace nlohmann -{ -namespace detail -{ -/////////////////// -// serialization // -/////////////////// - -/// how to treat decoding errors -enum class error_handler_t -{ - strict, ///< throw a type_error exception in case of invalid UTF-8 - replace, ///< replace invalid UTF-8 sequences with U+FFFD - ignore ///< ignore invalid UTF-8 sequences -}; - -template -class serializer -{ - using string_t = typename BasicJsonType::string_t; - using number_float_t = typename BasicJsonType::number_float_t; - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using binary_char_t = typename BasicJsonType::binary_t::value_type; - static constexpr std::uint8_t UTF8_ACCEPT = 0; - static constexpr std::uint8_t UTF8_REJECT = 1; - - public: - /*! - @param[in] s output stream to serialize to - @param[in] ichar indentation character to use - @param[in] error_handler_ how to react on decoding errors - */ - serializer(output_adapter_t s, const char ichar, - error_handler_t error_handler_ = error_handler_t::strict) - : o(std::move(s)) - , loc(std::localeconv()) - , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits::to_char_type(* (loc->thousands_sep))) - , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits::to_char_type(* (loc->decimal_point))) - , indent_char(ichar) - , indent_string(512, indent_char) - , error_handler(error_handler_) - {} - - // delete because of pointer members - serializer(const serializer&) = delete; - serializer& operator=(const serializer&) = delete; - serializer(serializer&&) = delete; - serializer& operator=(serializer&&) = delete; - ~serializer() = default; - - /*! - @brief internal implementation of the serialization function - - This function is called by the public member function dump and organizes - the serialization internally. The indentation level is propagated as - additional parameter. In case of arrays and objects, the function is - called recursively. - - - strings and object keys are escaped using `escape_string()` - - integer numbers are converted implicitly via `operator<<` - - floating-point numbers are converted to a string using `"%g"` format - - binary values are serialized as objects containing the subtype and the - byte array - - @param[in] val value to serialize - @param[in] pretty_print whether the output shall be pretty-printed - @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters - in the output are escaped with `\uXXXX` sequences, and the result consists - of ASCII characters only. - @param[in] indent_step the indent level - @param[in] current_indent the current indent level (only used internally) - */ - void dump(const BasicJsonType& val, - const bool pretty_print, - const bool ensure_ascii, - const unsigned int indent_step, - const unsigned int current_indent = 0) - { - switch (val.m_type) - { - case value_t::object: - { - if (val.m_value.object->empty()) - { - o->write_characters("{}", 2); - return; - } - - if (pretty_print) - { - o->write_characters("{\n", 2); - - // variable to hold indentation for recursive calls - const auto new_indent = current_indent + indent_step; - if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent)) - { - indent_string.resize(indent_string.size() * 2, ' '); - } - - // first n-1 elements - auto i = val.m_value.object->cbegin(); - for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i) - { - o->write_characters(indent_string.c_str(), new_indent); - o->write_character('\"'); - dump_escaped(i->first, ensure_ascii); - o->write_characters("\": ", 3); - dump(i->second, true, ensure_ascii, indent_step, new_indent); - o->write_characters(",\n", 2); - } - - // last element - JSON_ASSERT(i != val.m_value.object->cend()); - JSON_ASSERT(std::next(i) == val.m_value.object->cend()); - o->write_characters(indent_string.c_str(), new_indent); - o->write_character('\"'); - dump_escaped(i->first, ensure_ascii); - o->write_characters("\": ", 3); - dump(i->second, true, ensure_ascii, indent_step, new_indent); - - o->write_character('\n'); - o->write_characters(indent_string.c_str(), current_indent); - o->write_character('}'); - } - else - { - o->write_character('{'); - - // first n-1 elements - auto i = val.m_value.object->cbegin(); - for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i) - { - o->write_character('\"'); - dump_escaped(i->first, ensure_ascii); - o->write_characters("\":", 2); - dump(i->second, false, ensure_ascii, indent_step, current_indent); - o->write_character(','); - } - - // last element - JSON_ASSERT(i != val.m_value.object->cend()); - JSON_ASSERT(std::next(i) == val.m_value.object->cend()); - o->write_character('\"'); - dump_escaped(i->first, ensure_ascii); - o->write_characters("\":", 2); - dump(i->second, false, ensure_ascii, indent_step, current_indent); - - o->write_character('}'); - } - - return; - } - - case value_t::array: - { - if (val.m_value.array->empty()) - { - o->write_characters("[]", 2); - return; - } - - if (pretty_print) - { - o->write_characters("[\n", 2); - - // variable to hold indentation for recursive calls - const auto new_indent = current_indent + indent_step; - if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent)) - { - indent_string.resize(indent_string.size() * 2, ' '); - } - - // first n-1 elements - for (auto i = val.m_value.array->cbegin(); - i != val.m_value.array->cend() - 1; ++i) - { - o->write_characters(indent_string.c_str(), new_indent); - dump(*i, true, ensure_ascii, indent_step, new_indent); - o->write_characters(",\n", 2); - } - - // last element - JSON_ASSERT(!val.m_value.array->empty()); - o->write_characters(indent_string.c_str(), new_indent); - dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent); - - o->write_character('\n'); - o->write_characters(indent_string.c_str(), current_indent); - o->write_character(']'); - } - else - { - o->write_character('['); - - // first n-1 elements - for (auto i = val.m_value.array->cbegin(); - i != val.m_value.array->cend() - 1; ++i) - { - dump(*i, false, ensure_ascii, indent_step, current_indent); - o->write_character(','); - } - - // last element - JSON_ASSERT(!val.m_value.array->empty()); - dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent); - - o->write_character(']'); - } - - return; - } - - case value_t::string: - { - o->write_character('\"'); - dump_escaped(*val.m_value.string, ensure_ascii); - o->write_character('\"'); - return; - } - - case value_t::binary: - { - if (pretty_print) - { - o->write_characters("{\n", 2); - - // variable to hold indentation for recursive calls - const auto new_indent = current_indent + indent_step; - if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent)) - { - indent_string.resize(indent_string.size() * 2, ' '); - } - - o->write_characters(indent_string.c_str(), new_indent); - - o->write_characters("\"bytes\": [", 10); - - if (!val.m_value.binary->empty()) - { - for (auto i = val.m_value.binary->cbegin(); - i != val.m_value.binary->cend() - 1; ++i) - { - dump_integer(*i); - o->write_characters(", ", 2); - } - dump_integer(val.m_value.binary->back()); - } - - o->write_characters("],\n", 3); - o->write_characters(indent_string.c_str(), new_indent); - - o->write_characters("\"subtype\": ", 11); - if (val.m_value.binary->has_subtype()) - { - dump_integer(val.m_value.binary->subtype()); - } - else - { - o->write_characters("null", 4); - } - o->write_character('\n'); - o->write_characters(indent_string.c_str(), current_indent); - o->write_character('}'); - } - else - { - o->write_characters("{\"bytes\":[", 10); - - if (!val.m_value.binary->empty()) - { - for (auto i = val.m_value.binary->cbegin(); - i != val.m_value.binary->cend() - 1; ++i) - { - dump_integer(*i); - o->write_character(','); - } - dump_integer(val.m_value.binary->back()); - } - - o->write_characters("],\"subtype\":", 12); - if (val.m_value.binary->has_subtype()) - { - dump_integer(val.m_value.binary->subtype()); - o->write_character('}'); - } - else - { - o->write_characters("null}", 5); - } - } - return; - } - - case value_t::boolean: - { - if (val.m_value.boolean) - { - o->write_characters("true", 4); - } - else - { - o->write_characters("false", 5); - } - return; - } - - case value_t::number_integer: - { - dump_integer(val.m_value.number_integer); - return; - } - - case value_t::number_unsigned: - { - dump_integer(val.m_value.number_unsigned); - return; - } - - case value_t::number_float: - { - dump_float(val.m_value.number_float); - return; - } - - case value_t::discarded: - { - o->write_characters("", 11); - return; - } - - case value_t::null: - { - o->write_characters("null", 4); - return; - } - - default: // LCOV_EXCL_LINE - JSON_ASSERT(false); // LCOV_EXCL_LINE - } - } - - private: - /*! - @brief dump escaped string - - Escape a string by replacing certain special characters by a sequence of an - escape character (backslash) and another character and other control - characters by a sequence of "\u" followed by a four-digit hex - representation. The escaped string is written to output stream @a o. - - @param[in] s the string to escape - @param[in] ensure_ascii whether to escape non-ASCII characters with - \uXXXX sequences - - @complexity Linear in the length of string @a s. - */ - void dump_escaped(const string_t& s, const bool ensure_ascii) - { - std::uint32_t codepoint; - std::uint8_t state = UTF8_ACCEPT; - std::size_t bytes = 0; // number of bytes written to string_buffer - - // number of bytes written at the point of the last valid byte - std::size_t bytes_after_last_accept = 0; - std::size_t undumped_chars = 0; - - for (std::size_t i = 0; i < s.size(); ++i) - { - const auto byte = static_cast(s[i]); - - switch (decode(state, codepoint, byte)) - { - case UTF8_ACCEPT: // decode found a new code point - { - switch (codepoint) - { - case 0x08: // backspace - { - string_buffer[bytes++] = '\\'; - string_buffer[bytes++] = 'b'; - break; - } - - case 0x09: // horizontal tab - { - string_buffer[bytes++] = '\\'; - string_buffer[bytes++] = 't'; - break; - } - - case 0x0A: // newline - { - string_buffer[bytes++] = '\\'; - string_buffer[bytes++] = 'n'; - break; - } - - case 0x0C: // formfeed - { - string_buffer[bytes++] = '\\'; - string_buffer[bytes++] = 'f'; - break; - } - - case 0x0D: // carriage return - { - string_buffer[bytes++] = '\\'; - string_buffer[bytes++] = 'r'; - break; - } - - case 0x22: // quotation mark - { - string_buffer[bytes++] = '\\'; - string_buffer[bytes++] = '\"'; - break; - } - - case 0x5C: // reverse solidus - { - string_buffer[bytes++] = '\\'; - string_buffer[bytes++] = '\\'; - break; - } - - default: - { - // escape control characters (0x00..0x1F) or, if - // ensure_ascii parameter is used, non-ASCII characters - if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F))) - { - if (codepoint <= 0xFFFF) - { - (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x", - static_cast(codepoint)); - bytes += 6; - } - else - { - (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x", - static_cast(0xD7C0u + (codepoint >> 10u)), - static_cast(0xDC00u + (codepoint & 0x3FFu))); - bytes += 12; - } - } - else - { - // copy byte to buffer (all previous bytes - // been copied have in default case above) - string_buffer[bytes++] = s[i]; - } - break; - } - } - - // write buffer and reset index; there must be 13 bytes - // left, as this is the maximal number of bytes to be - // written ("\uxxxx\uxxxx\0") for one code point - if (string_buffer.size() - bytes < 13) - { - o->write_characters(string_buffer.data(), bytes); - bytes = 0; - } - - // remember the byte position of this accept - bytes_after_last_accept = bytes; - undumped_chars = 0; - break; - } - - case UTF8_REJECT: // decode found invalid UTF-8 byte - { - switch (error_handler) - { - case error_handler_t::strict: - { - std::string sn(3, '\0'); - (std::snprintf)(&sn[0], sn.size(), "%.2X", byte); - JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn)); - } - - case error_handler_t::ignore: - case error_handler_t::replace: - { - // in case we saw this character the first time, we - // would like to read it again, because the byte - // may be OK for itself, but just not OK for the - // previous sequence - if (undumped_chars > 0) - { - --i; - } - - // reset length buffer to the last accepted index; - // thus removing/ignoring the invalid characters - bytes = bytes_after_last_accept; - - if (error_handler == error_handler_t::replace) - { - // add a replacement character - if (ensure_ascii) - { - string_buffer[bytes++] = '\\'; - string_buffer[bytes++] = 'u'; - string_buffer[bytes++] = 'f'; - string_buffer[bytes++] = 'f'; - string_buffer[bytes++] = 'f'; - string_buffer[bytes++] = 'd'; - } - else - { - string_buffer[bytes++] = detail::binary_writer::to_char_type('\xEF'); - string_buffer[bytes++] = detail::binary_writer::to_char_type('\xBF'); - string_buffer[bytes++] = detail::binary_writer::to_char_type('\xBD'); - } - - // write buffer and reset index; there must be 13 bytes - // left, as this is the maximal number of bytes to be - // written ("\uxxxx\uxxxx\0") for one code point - if (string_buffer.size() - bytes < 13) - { - o->write_characters(string_buffer.data(), bytes); - bytes = 0; - } - - bytes_after_last_accept = bytes; - } - - undumped_chars = 0; - - // continue processing the string - state = UTF8_ACCEPT; - break; - } - - default: // LCOV_EXCL_LINE - JSON_ASSERT(false); // LCOV_EXCL_LINE - } - break; - } - - default: // decode found yet incomplete multi-byte code point - { - if (!ensure_ascii) - { - // code point will not be escaped - copy byte to buffer - string_buffer[bytes++] = s[i]; - } - ++undumped_chars; - break; - } - } - } - - // we finished processing the string - if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT)) - { - // write buffer - if (bytes > 0) - { - o->write_characters(string_buffer.data(), bytes); - } - } - else - { - // we finish reading, but do not accept: string was incomplete - switch (error_handler) - { - case error_handler_t::strict: - { - std::string sn(3, '\0'); - (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast(s.back())); - JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn)); - } - - case error_handler_t::ignore: - { - // write all accepted bytes - o->write_characters(string_buffer.data(), bytes_after_last_accept); - break; - } - - case error_handler_t::replace: - { - // write all accepted bytes - o->write_characters(string_buffer.data(), bytes_after_last_accept); - // add a replacement character - if (ensure_ascii) - { - o->write_characters("\\ufffd", 6); - } - else - { - o->write_characters("\xEF\xBF\xBD", 3); - } - break; - } - - default: // LCOV_EXCL_LINE - JSON_ASSERT(false); // LCOV_EXCL_LINE - } - } - } - - /*! - @brief count digits - - Count the number of decimal (base 10) digits for an input unsigned integer. - - @param[in] x unsigned integer number to count its digits - @return number of decimal digits - */ - inline unsigned int count_digits(number_unsigned_t x) noexcept - { - unsigned int n_digits = 1; - for (;;) - { - if (x < 10) - { - return n_digits; - } - if (x < 100) - { - return n_digits + 1; - } - if (x < 1000) - { - return n_digits + 2; - } - if (x < 10000) - { - return n_digits + 3; - } - x = x / 10000u; - n_digits += 4; - } - } - - /*! - @brief dump an integer - - Dump a given integer to output stream @a o. Works internally with - @a number_buffer. - - @param[in] x integer number (signed or unsigned) to dump - @tparam NumberType either @a number_integer_t or @a number_unsigned_t - */ - template < typename NumberType, detail::enable_if_t < - std::is_same::value || - std::is_same::value || - std::is_same::value, - int > = 0 > - void dump_integer(NumberType x) - { - static constexpr std::array, 100> digits_to_99 - { - { - {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}}, - {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}}, - {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}}, - {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}}, - {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}}, - {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}}, - {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}}, - {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}}, - {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}}, - {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}}, - } - }; - - // special case for "0" - if (x == 0) - { - o->write_character('0'); - return; - } - - // use a pointer to fill the buffer - auto buffer_ptr = number_buffer.begin(); - - const bool is_negative = std::is_same::value && !(x >= 0); // see issue #755 - number_unsigned_t abs_value; - - unsigned int n_chars; - - if (is_negative) - { - *buffer_ptr = '-'; - abs_value = remove_sign(static_cast(x)); - - // account one more byte for the minus sign - n_chars = 1 + count_digits(abs_value); - } - else - { - abs_value = static_cast(x); - n_chars = count_digits(abs_value); - } - - // spare 1 byte for '\0' - JSON_ASSERT(n_chars < number_buffer.size() - 1); - - // jump to the end to generate the string from backward - // so we later avoid reversing the result - buffer_ptr += n_chars; - - // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu - // See: https://www.youtube.com/watch?v=o4-CwDo2zpg - while (abs_value >= 100) - { - const auto digits_index = static_cast((abs_value % 100)); - abs_value /= 100; - *(--buffer_ptr) = digits_to_99[digits_index][1]; - *(--buffer_ptr) = digits_to_99[digits_index][0]; - } - - if (abs_value >= 10) - { - const auto digits_index = static_cast(abs_value); - *(--buffer_ptr) = digits_to_99[digits_index][1]; - *(--buffer_ptr) = digits_to_99[digits_index][0]; - } - else - { - *(--buffer_ptr) = static_cast('0' + abs_value); - } - - o->write_characters(number_buffer.data(), n_chars); - } - - /*! - @brief dump a floating-point number - - Dump a given floating-point number to output stream @a o. Works internally - with @a number_buffer. - - @param[in] x floating-point number to dump - */ - void dump_float(number_float_t x) - { - // NaN / inf - if (!std::isfinite(x)) - { - o->write_characters("null", 4); - return; - } - - // If number_float_t is an IEEE-754 single or double precision number, - // use the Grisu2 algorithm to produce short numbers which are - // guaranteed to round-trip, using strtof and strtod, resp. - // - // NB: The test below works if == . - static constexpr bool is_ieee_single_or_double - = (std::numeric_limits::is_iec559 && std::numeric_limits::digits == 24 && std::numeric_limits::max_exponent == 128) || - (std::numeric_limits::is_iec559 && std::numeric_limits::digits == 53 && std::numeric_limits::max_exponent == 1024); - - dump_float(x, std::integral_constant()); - } - - void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/) - { - char* begin = number_buffer.data(); - char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x); - - o->write_characters(begin, static_cast(end - begin)); - } - - void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/) - { - // get number of digits for a float -> text -> float round-trip - static constexpr auto d = std::numeric_limits::max_digits10; - - // the actual conversion - std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x); - - // negative value indicates an error - JSON_ASSERT(len > 0); - // check if buffer was large enough - JSON_ASSERT(static_cast(len) < number_buffer.size()); - - // erase thousands separator - if (thousands_sep != '\0') - { - const auto end = std::remove(number_buffer.begin(), - number_buffer.begin() + len, thousands_sep); - std::fill(end, number_buffer.end(), '\0'); - JSON_ASSERT((end - number_buffer.begin()) <= len); - len = (end - number_buffer.begin()); - } - - // convert decimal point to '.' - if (decimal_point != '\0' && decimal_point != '.') - { - const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point); - if (dec_pos != number_buffer.end()) - { - *dec_pos = '.'; - } - } - - o->write_characters(number_buffer.data(), static_cast(len)); - - // determine if need to append ".0" - const bool value_is_int_like = - std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1, - [](char c) - { - return c == '.' || c == 'e'; - }); - - if (value_is_int_like) - { - o->write_characters(".0", 2); - } - } - - /*! - @brief check whether a string is UTF-8 encoded - - The function checks each byte of a string whether it is UTF-8 encoded. The - result of the check is stored in the @a state parameter. The function must - be called initially with state 0 (accept). State 1 means the string must - be rejected, because the current byte is not allowed. If the string is - completely processed, but the state is non-zero, the string ended - prematurely; that is, the last byte indicated more bytes should have - followed. - - @param[in,out] state the state of the decoding - @param[in,out] codep codepoint (valid only if resulting state is UTF8_ACCEPT) - @param[in] byte next byte to decode - @return new state - - @note The function has been edited: a std::array is used. - - @copyright Copyright (c) 2008-2009 Bjoern Hoehrmann - @sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ - */ - static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept - { - static const std::array utf8d = - { - { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF - 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF - 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF - 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF - 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2 - 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4 - 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6 - 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8 - } - }; - - const std::uint8_t type = utf8d[byte]; - - codep = (state != UTF8_ACCEPT) - ? (byte & 0x3fu) | (codep << 6u) - : (0xFFu >> type) & (byte); - - std::size_t index = 256u + static_cast(state) * 16u + static_cast(type); - JSON_ASSERT(index < 400); - state = utf8d[index]; - return state; - } - - /* - * Overload to make the compiler happy while it is instantiating - * dump_integer for number_unsigned_t. - * Must never be called. - */ - number_unsigned_t remove_sign(number_unsigned_t x) - { - JSON_ASSERT(false); // LCOV_EXCL_LINE - return x; // LCOV_EXCL_LINE - } - - /* - * Helper function for dump_integer - * - * This function takes a negative signed integer and returns its absolute - * value as unsigned integer. The plus/minus shuffling is necessary as we can - * not directly remove the sign of an arbitrary signed integer as the - * absolute values of INT_MIN and INT_MAX are usually not the same. See - * #1708 for details. - */ - inline number_unsigned_t remove_sign(number_integer_t x) noexcept - { - JSON_ASSERT(x < 0 && x < (std::numeric_limits::max)()); - return static_cast(-(x + 1)) + 1; - } - - private: - /// the output of the serializer - output_adapter_t o = nullptr; - - /// a (hopefully) large enough character buffer - std::array number_buffer{{}}; - - /// the locale - const std::lconv* loc = nullptr; - /// the locale's thousand separator character - const char thousands_sep = '\0'; - /// the locale's decimal point character - const char decimal_point = '\0'; - - /// string buffer - std::array string_buffer{{}}; - - /// the indentation character - const char indent_char; - /// the indentation string - string_t indent_string; - - /// error_handler how to react on decoding errors - const error_handler_t error_handler; -}; -} // namespace detail -} // namespace nlohmann - -// #include - -// #include - -// #include - - -#include // less -#include // allocator -#include // pair -#include // vector - -namespace nlohmann -{ - -/// ordered_map: a minimal map-like container that preserves insertion order -/// for use within nlohmann::basic_json -template , - class Allocator = std::allocator>> - struct ordered_map : std::vector, Allocator> -{ - using key_type = Key; - using mapped_type = T; - using Container = std::vector, Allocator>; - using typename Container::iterator; - using typename Container::const_iterator; - using typename Container::size_type; - using typename Container::value_type; - - // Explicit constructors instead of `using Container::Container` - // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4) - ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {} - template - ordered_map(It first, It last, const Allocator& alloc = Allocator()) - : Container{first, last, alloc} {} - ordered_map(std::initializer_list init, const Allocator& alloc = Allocator() ) - : Container{init, alloc} {} - - std::pair emplace(const key_type& key, T&& t) - { - for (auto it = this->begin(); it != this->end(); ++it) - { - if (it->first == key) - { - return {it, false}; - } - } - Container::emplace_back(key, t); - return {--this->end(), true}; - } - - T& operator[](const Key& key) - { - return emplace(key, T{}).first->second; - } - - const T& operator[](const Key& key) const - { - return at(key); - } - - T& at(const Key& key) - { - for (auto it = this->begin(); it != this->end(); ++it) - { - if (it->first == key) - { - return it->second; - } - } - - throw std::out_of_range("key not found"); - } - - const T& at(const Key& key) const - { - for (auto it = this->begin(); it != this->end(); ++it) - { - if (it->first == key) - { - return it->second; - } - } - - throw std::out_of_range("key not found"); - } - - size_type erase(const Key& key) - { - for (auto it = this->begin(); it != this->end(); ++it) - { - if (it->first == key) - { - // Since we cannot move const Keys, re-construct them in place - for (auto next = it; ++next != this->end(); ++it) - { - it->~value_type(); // Destroy but keep allocation - new (&*it) value_type{std::move(*next)}; - } - Container::pop_back(); - return 1; - } - } - return 0; - } - - iterator erase(iterator pos) - { - auto it = pos; - - // Since we cannot move const Keys, re-construct them in place - for (auto next = it; ++next != this->end(); ++it) - { - it->~value_type(); // Destroy but keep allocation - new (&*it) value_type{std::move(*next)}; - } - Container::pop_back(); - return pos; - } - - size_type count(const Key& key) const - { - for (auto it = this->begin(); it != this->end(); ++it) - { - if (it->first == key) - { - return 1; - } - } - return 0; - } - - iterator find(const Key& key) - { - for (auto it = this->begin(); it != this->end(); ++it) - { - if (it->first == key) - { - return it; - } - } - return Container::end(); - } - - const_iterator find(const Key& key) const - { - for (auto it = this->begin(); it != this->end(); ++it) - { - if (it->first == key) - { - return it; - } - } - return Container::end(); - } - - std::pair insert( value_type&& value ) - { - return emplace(value.first, std::move(value.second)); - } - - std::pair insert( const value_type& value ) - { - for (auto it = this->begin(); it != this->end(); ++it) - { - if (it->first == value.first) - { - return {it, false}; - } - } - Container::push_back(value); - return {--this->end(), true}; - } -}; - -} // namespace nlohmann - - -/*! -@brief namespace for Niels Lohmann -@see https://github.com/nlohmann -@since version 1.0.0 -*/ -namespace nlohmann -{ - -/*! -@brief a class to store JSON values - -@tparam ObjectType type for JSON objects (`std::map` by default; will be used -in @ref object_t) -@tparam ArrayType type for JSON arrays (`std::vector` by default; will be used -in @ref array_t) -@tparam StringType type for JSON strings and object keys (`std::string` by -default; will be used in @ref string_t) -@tparam BooleanType type for JSON booleans (`bool` by default; will be used -in @ref boolean_t) -@tparam NumberIntegerType type for JSON integer numbers (`int64_t` by -default; will be used in @ref number_integer_t) -@tparam NumberUnsignedType type for JSON unsigned integer numbers (@c -`uint64_t` by default; will be used in @ref number_unsigned_t) -@tparam NumberFloatType type for JSON floating-point numbers (`double` by -default; will be used in @ref number_float_t) -@tparam BinaryType type for packed binary data for compatibility with binary -serialization formats (`std::vector` by default; will be used in -@ref binary_t) -@tparam AllocatorType type of the allocator to use (`std::allocator` by -default) -@tparam JSONSerializer the serializer to resolve internal calls to `to_json()` -and `from_json()` (@ref adl_serializer by default) - -@requirement The class satisfies the following concept requirements: -- Basic - - [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible): - JSON values can be default constructed. The result will be a JSON null - value. - - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible): - A JSON value can be constructed from an rvalue argument. - - [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible): - A JSON value can be copy-constructed from an lvalue expression. - - [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable): - A JSON value van be assigned from an rvalue argument. - - [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable): - A JSON value can be copy-assigned from an lvalue expression. - - [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible): - JSON values can be destructed. -- Layout - - [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType): - JSON values have - [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout): - All non-static data members are private and standard layout types, the - class has no virtual functions or (virtual) base classes. -- Library-wide - - [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable): - JSON values can be compared with `==`, see @ref - operator==(const_reference,const_reference). - - [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable): - JSON values can be compared with `<`, see @ref - operator<(const_reference,const_reference). - - [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable): - Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of - other compatible types, using unqualified function call @ref swap(). - - [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer): - JSON values can be compared against `std::nullptr_t` objects which are used - to model the `null` value. -- Container - - [Container](https://en.cppreference.com/w/cpp/named_req/Container): - JSON values can be used like STL containers and provide iterator access. - - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer); - JSON values can be used like STL containers and provide reverse iterator - access. - -@invariant The member variables @a m_value and @a m_type have the following -relationship: -- If `m_type == value_t::object`, then `m_value.object != nullptr`. -- If `m_type == value_t::array`, then `m_value.array != nullptr`. -- If `m_type == value_t::string`, then `m_value.string != nullptr`. -The invariants are checked by member function assert_invariant(). - -@internal -@note ObjectType trick from https://stackoverflow.com/a/9860911 -@endinternal - -@see [RFC 7159: The JavaScript Object Notation (JSON) Data Interchange -Format](http://rfc7159.net/rfc7159) - -@since version 1.0.0 - -@nosubgrouping -*/ -NLOHMANN_BASIC_JSON_TPL_DECLARATION -class basic_json -{ - private: - template friend struct detail::external_constructor; - friend ::nlohmann::json_pointer; - - template - friend class ::nlohmann::detail::parser; - friend ::nlohmann::detail::serializer; - template - friend class ::nlohmann::detail::iter_impl; - template - friend class ::nlohmann::detail::binary_writer; - template - friend class ::nlohmann::detail::binary_reader; - template - friend class ::nlohmann::detail::json_sax_dom_parser; - template - friend class ::nlohmann::detail::json_sax_dom_callback_parser; - - /// workaround type for MSVC - using basic_json_t = NLOHMANN_BASIC_JSON_TPL; - - // convenience aliases for types residing in namespace detail; - using lexer = ::nlohmann::detail::lexer_base; - - template - static ::nlohmann::detail::parser parser( - InputAdapterType adapter, - detail::parser_callback_tcb = nullptr, - const bool allow_exceptions = true, - const bool ignore_comments = false - ) - { - return ::nlohmann::detail::parser(std::move(adapter), - std::move(cb), allow_exceptions, ignore_comments); - } - - using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t; - template - using internal_iterator = ::nlohmann::detail::internal_iterator; - template - using iter_impl = ::nlohmann::detail::iter_impl; - template - using iteration_proxy = ::nlohmann::detail::iteration_proxy; - template using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator; - - template - using output_adapter_t = ::nlohmann::detail::output_adapter_t; - - template - using binary_reader = ::nlohmann::detail::binary_reader; - template using binary_writer = ::nlohmann::detail::binary_writer; - - using serializer = ::nlohmann::detail::serializer; - - public: - using value_t = detail::value_t; - /// JSON Pointer, see @ref nlohmann::json_pointer - using json_pointer = ::nlohmann::json_pointer; - template - using json_serializer = JSONSerializer; - /// how to treat decoding errors - using error_handler_t = detail::error_handler_t; - /// how to treat CBOR tags - using cbor_tag_handler_t = detail::cbor_tag_handler_t; - /// helper type for initializer lists of basic_json values - using initializer_list_t = std::initializer_list>; - - using input_format_t = detail::input_format_t; - /// SAX interface type, see @ref nlohmann::json_sax - using json_sax_t = json_sax; - - //////////////// - // exceptions // - //////////////// - - /// @name exceptions - /// Classes to implement user-defined exceptions. - /// @{ - - /// @copydoc detail::exception - using exception = detail::exception; - /// @copydoc detail::parse_error - using parse_error = detail::parse_error; - /// @copydoc detail::invalid_iterator - using invalid_iterator = detail::invalid_iterator; - /// @copydoc detail::type_error - using type_error = detail::type_error; - /// @copydoc detail::out_of_range - using out_of_range = detail::out_of_range; - /// @copydoc detail::other_error - using other_error = detail::other_error; - - /// @} - - - ///////////////////// - // container types // - ///////////////////// - - /// @name container types - /// The canonic container types to use @ref basic_json like any other STL - /// container. - /// @{ - - /// the type of elements in a basic_json container - using value_type = basic_json; - - /// the type of an element reference - using reference = value_type&; - /// the type of an element const reference - using const_reference = const value_type&; - - /// a type to represent differences between iterators - using difference_type = std::ptrdiff_t; - /// a type to represent container sizes - using size_type = std::size_t; - - /// the allocator type - using allocator_type = AllocatorType; - - /// the type of an element pointer - using pointer = typename std::allocator_traits::pointer; - /// the type of an element const pointer - using const_pointer = typename std::allocator_traits::const_pointer; - - /// an iterator for a basic_json container - using iterator = iter_impl; - /// a const iterator for a basic_json container - using const_iterator = iter_impl; - /// a reverse iterator for a basic_json container - using reverse_iterator = json_reverse_iterator; - /// a const reverse iterator for a basic_json container - using const_reverse_iterator = json_reverse_iterator; - - /// @} - - - /*! - @brief returns the allocator associated with the container - */ - static allocator_type get_allocator() - { - return allocator_type(); - } - - /*! - @brief returns version information on the library - - This function returns a JSON object with information about the library, - including the version number and information on the platform and compiler. - - @return JSON object holding version information - key | description - ----------- | --------------- - `compiler` | Information on the used compiler. It is an object with the following keys: `c++` (the used C++ standard), `family` (the compiler family; possible values are `clang`, `icc`, `gcc`, `ilecpp`, `msvc`, `pgcpp`, `sunpro`, and `unknown`), and `version` (the compiler version). - `copyright` | The copyright line for the library as string. - `name` | The name of the library as string. - `platform` | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`. - `url` | The URL of the project as string. - `version` | The version of the library. It is an object with the following keys: `major`, `minor`, and `patch` as defined by [Semantic Versioning](http://semver.org), and `string` (the version string). - - @liveexample{The following code shows an example output of the `meta()` - function.,meta} - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @complexity Constant. - - @since 2.1.0 - */ - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json meta() - { - basic_json result; - - result["copyright"] = "(C) 2013-2020 Niels Lohmann"; - result["name"] = "JSON for Modern C++"; - result["url"] = "https://github.com/nlohmann/json"; - result["version"]["string"] = - std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." + - std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." + - std::to_string(NLOHMANN_JSON_VERSION_PATCH); - result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR; - result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR; - result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH; - -#ifdef _WIN32 - result["platform"] = "win32"; -#elif defined __linux__ - result["platform"] = "linux"; -#elif defined __APPLE__ - result["platform"] = "apple"; -#elif defined __unix__ - result["platform"] = "unix"; -#else - result["platform"] = "unknown"; -#endif - -#if defined(__ICC) || defined(__INTEL_COMPILER) - result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}}; -#elif defined(__clang__) - result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}}; -#elif defined(__GNUC__) || defined(__GNUG__) - result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}}; -#elif defined(__HP_cc) || defined(__HP_aCC) - result["compiler"] = "hp" -#elif defined(__IBMCPP__) - result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}}; -#elif defined(_MSC_VER) - result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}}; -#elif defined(__PGI) - result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}}; -#elif defined(__SUNPRO_CC) - result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}}; -#else - result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}}; -#endif - -#ifdef __cplusplus - result["compiler"]["c++"] = std::to_string(__cplusplus); -#else - result["compiler"]["c++"] = "unknown"; -#endif - return result; - } - - - /////////////////////////// - // JSON value data types // - /////////////////////////// - - /// @name JSON value data types - /// The data types to store a JSON value. These types are derived from - /// the template arguments passed to class @ref basic_json. - /// @{ - -#if defined(JSON_HAS_CPP_14) - // Use transparent comparator if possible, combined with perfect forwarding - // on find() and count() calls prevents unnecessary string construction. - using object_comparator_t = std::less<>; -#else - using object_comparator_t = std::less; -#endif - - /*! - @brief a type for an object - - [RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows: - > An object is an unordered collection of zero or more name/value pairs, - > where a name is a string and a value is a string, number, boolean, null, - > object, or array. - - To store objects in C++, a type is defined by the template parameters - described below. - - @tparam ObjectType the container to store objects (e.g., `std::map` or - `std::unordered_map`) - @tparam StringType the type of the keys or names (e.g., `std::string`). - The comparison function `std::less` is used to order elements - inside the container. - @tparam AllocatorType the allocator to use for objects (e.g., - `std::allocator`) - - #### Default type - - With the default values for @a ObjectType (`std::map`), @a StringType - (`std::string`), and @a AllocatorType (`std::allocator`), the default - value for @a object_t is: - - @code {.cpp} - std::map< - std::string, // key_type - basic_json, // value_type - std::less, // key_compare - std::allocator> // allocator_type - > - @endcode - - #### Behavior - - The choice of @a object_t influences the behavior of the JSON class. With - the default type, objects have the following behavior: - - - When all names are unique, objects will be interoperable in the sense - that all software implementations receiving that object will agree on - the name-value mappings. - - When the names within an object are not unique, it is unspecified which - one of the values for a given key will be chosen. For instance, - `{"key": 2, "key": 1}` could be equal to either `{"key": 1}` or - `{"key": 2}`. - - Internally, name/value pairs are stored in lexicographical order of the - names. Objects will also be serialized (see @ref dump) in this order. - For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored - and serialized as `{"a": 2, "b": 1}`. - - When comparing objects, the order of the name/value pairs is irrelevant. - This makes objects interoperable in the sense that they will not be - affected by these differences. For instance, `{"b": 1, "a": 2}` and - `{"a": 2, "b": 1}` will be treated as equal. - - #### Limits - - [RFC 7159](http://rfc7159.net/rfc7159) specifies: - > An implementation may set limits on the maximum depth of nesting. - - In this class, the object's limit of nesting is not explicitly constrained. - However, a maximum depth of nesting may be introduced by the compiler or - runtime environment. A theoretical limit can be queried by calling the - @ref max_size function of a JSON object. - - #### Storage - - Objects are stored as pointers in a @ref basic_json type. That is, for any - access to object values, a pointer of type `object_t*` must be - dereferenced. - - @sa @ref array_t -- type for an array value - - @since version 1.0.0 - - @note The order name/value pairs are added to the object is *not* - preserved by the library. Therefore, iterating an object may return - name/value pairs in a different order than they were originally stored. In - fact, keys will be traversed in alphabetical order as `std::map` with - `std::less` is used by default. Please note this behavior conforms to [RFC - 7159](http://rfc7159.net/rfc7159), because any order implements the - specified "unordered" nature of JSON objects. - */ - using object_t = ObjectType>>; - - /*! - @brief a type for an array - - [RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows: - > An array is an ordered sequence of zero or more values. - - To store objects in C++, a type is defined by the template parameters - explained below. - - @tparam ArrayType container type to store arrays (e.g., `std::vector` or - `std::list`) - @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`) - - #### Default type - - With the default values for @a ArrayType (`std::vector`) and @a - AllocatorType (`std::allocator`), the default value for @a array_t is: - - @code {.cpp} - std::vector< - basic_json, // value_type - std::allocator // allocator_type - > - @endcode - - #### Limits - - [RFC 7159](http://rfc7159.net/rfc7159) specifies: - > An implementation may set limits on the maximum depth of nesting. - - In this class, the array's limit of nesting is not explicitly constrained. - However, a maximum depth of nesting may be introduced by the compiler or - runtime environment. A theoretical limit can be queried by calling the - @ref max_size function of a JSON array. - - #### Storage - - Arrays are stored as pointers in a @ref basic_json type. That is, for any - access to array values, a pointer of type `array_t*` must be dereferenced. - - @sa @ref object_t -- type for an object value - - @since version 1.0.0 - */ - using array_t = ArrayType>; - - /*! - @brief a type for a string - - [RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows: - > A string is a sequence of zero or more Unicode characters. - - To store objects in C++, a type is defined by the template parameter - described below. Unicode values are split by the JSON class into - byte-sized characters during deserialization. - - @tparam StringType the container to store strings (e.g., `std::string`). - Note this container is used for keys/names in objects, see @ref object_t. - - #### Default type - - With the default values for @a StringType (`std::string`), the default - value for @a string_t is: - - @code {.cpp} - std::string - @endcode - - #### Encoding - - Strings are stored in UTF-8 encoding. Therefore, functions like - `std::string::size()` or `std::string::length()` return the number of - bytes in the string rather than the number of characters or glyphs. - - #### String comparison - - [RFC 7159](http://rfc7159.net/rfc7159) states: - > Software implementations are typically required to test names of object - > members for equality. Implementations that transform the textual - > representation into sequences of Unicode code units and then perform the - > comparison numerically, code unit by code unit, are interoperable in the - > sense that implementations will agree in all cases on equality or - > inequality of two strings. For example, implementations that compare - > strings with escaped characters unconverted may incorrectly find that - > `"a\\b"` and `"a\u005Cb"` are not equal. - - This implementation is interoperable as it does compare strings code unit - by code unit. - - #### Storage - - String values are stored as pointers in a @ref basic_json type. That is, - for any access to string values, a pointer of type `string_t*` must be - dereferenced. - - @since version 1.0.0 - */ - using string_t = StringType; - - /*! - @brief a type for a boolean - - [RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a - type which differentiates the two literals `true` and `false`. - - To store objects in C++, a type is defined by the template parameter @a - BooleanType which chooses the type to use. - - #### Default type - - With the default values for @a BooleanType (`bool`), the default value for - @a boolean_t is: - - @code {.cpp} - bool - @endcode - - #### Storage - - Boolean values are stored directly inside a @ref basic_json type. - - @since version 1.0.0 - */ - using boolean_t = BooleanType; - - /*! - @brief a type for a number (integer) - - [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows: - > The representation of numbers is similar to that used in most - > programming languages. A number is represented in base 10 using decimal - > digits. It contains an integer component that may be prefixed with an - > optional minus sign, which may be followed by a fraction part and/or an - > exponent part. Leading zeros are not allowed. (...) Numeric values that - > cannot be represented in the grammar below (such as Infinity and NaN) - > are not permitted. - - This description includes both integer and floating-point numbers. - However, C++ allows more precise storage if it is known whether the number - is a signed integer, an unsigned integer or a floating-point number. - Therefore, three different types, @ref number_integer_t, @ref - number_unsigned_t and @ref number_float_t are used. - - To store integer numbers in C++, a type is defined by the template - parameter @a NumberIntegerType which chooses the type to use. - - #### Default type - - With the default values for @a NumberIntegerType (`int64_t`), the default - value for @a number_integer_t is: - - @code {.cpp} - int64_t - @endcode - - #### Default behavior - - - The restrictions about leading zeros is not enforced in C++. Instead, - leading zeros in integer literals lead to an interpretation as octal - number. Internally, the value will be stored as decimal number. For - instance, the C++ integer literal `010` will be serialized to `8`. - During deserialization, leading zeros yield an error. - - Not-a-number (NaN) values will be serialized to `null`. - - #### Limits - - [RFC 7159](http://rfc7159.net/rfc7159) specifies: - > An implementation may set limits on the range and precision of numbers. - - When the default type is used, the maximal integer number that can be - stored is `9223372036854775807` (INT64_MAX) and the minimal integer number - that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers - that are out of range will yield over/underflow when used in a - constructor. During deserialization, too large or small integer numbers - will be automatically be stored as @ref number_unsigned_t or @ref - number_float_t. - - [RFC 7159](http://rfc7159.net/rfc7159) further states: - > Note that when such software is used, numbers that are integers and are - > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense - > that implementations will agree exactly on their numeric values. - - As this range is a subrange of the exactly supported range [INT64_MIN, - INT64_MAX], this class's integer type is interoperable. - - #### Storage - - Integer number values are stored directly inside a @ref basic_json type. - - @sa @ref number_float_t -- type for number values (floating-point) - - @sa @ref number_unsigned_t -- type for number values (unsigned integer) - - @since version 1.0.0 - */ - using number_integer_t = NumberIntegerType; - - /*! - @brief a type for a number (unsigned) - - [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows: - > The representation of numbers is similar to that used in most - > programming languages. A number is represented in base 10 using decimal - > digits. It contains an integer component that may be prefixed with an - > optional minus sign, which may be followed by a fraction part and/or an - > exponent part. Leading zeros are not allowed. (...) Numeric values that - > cannot be represented in the grammar below (such as Infinity and NaN) - > are not permitted. - - This description includes both integer and floating-point numbers. - However, C++ allows more precise storage if it is known whether the number - is a signed integer, an unsigned integer or a floating-point number. - Therefore, three different types, @ref number_integer_t, @ref - number_unsigned_t and @ref number_float_t are used. - - To store unsigned integer numbers in C++, a type is defined by the - template parameter @a NumberUnsignedType which chooses the type to use. - - #### Default type - - With the default values for @a NumberUnsignedType (`uint64_t`), the - default value for @a number_unsigned_t is: - - @code {.cpp} - uint64_t - @endcode - - #### Default behavior - - - The restrictions about leading zeros is not enforced in C++. Instead, - leading zeros in integer literals lead to an interpretation as octal - number. Internally, the value will be stored as decimal number. For - instance, the C++ integer literal `010` will be serialized to `8`. - During deserialization, leading zeros yield an error. - - Not-a-number (NaN) values will be serialized to `null`. - - #### Limits - - [RFC 7159](http://rfc7159.net/rfc7159) specifies: - > An implementation may set limits on the range and precision of numbers. - - When the default type is used, the maximal integer number that can be - stored is `18446744073709551615` (UINT64_MAX) and the minimal integer - number that can be stored is `0`. Integer numbers that are out of range - will yield over/underflow when used in a constructor. During - deserialization, too large or small integer numbers will be automatically - be stored as @ref number_integer_t or @ref number_float_t. - - [RFC 7159](http://rfc7159.net/rfc7159) further states: - > Note that when such software is used, numbers that are integers and are - > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense - > that implementations will agree exactly on their numeric values. - - As this range is a subrange (when considered in conjunction with the - number_integer_t type) of the exactly supported range [0, UINT64_MAX], - this class's integer type is interoperable. - - #### Storage - - Integer number values are stored directly inside a @ref basic_json type. - - @sa @ref number_float_t -- type for number values (floating-point) - @sa @ref number_integer_t -- type for number values (integer) - - @since version 2.0.0 - */ - using number_unsigned_t = NumberUnsignedType; - - /*! - @brief a type for a number (floating-point) - - [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows: - > The representation of numbers is similar to that used in most - > programming languages. A number is represented in base 10 using decimal - > digits. It contains an integer component that may be prefixed with an - > optional minus sign, which may be followed by a fraction part and/or an - > exponent part. Leading zeros are not allowed. (...) Numeric values that - > cannot be represented in the grammar below (such as Infinity and NaN) - > are not permitted. - - This description includes both integer and floating-point numbers. - However, C++ allows more precise storage if it is known whether the number - is a signed integer, an unsigned integer or a floating-point number. - Therefore, three different types, @ref number_integer_t, @ref - number_unsigned_t and @ref number_float_t are used. - - To store floating-point numbers in C++, a type is defined by the template - parameter @a NumberFloatType which chooses the type to use. - - #### Default type - - With the default values for @a NumberFloatType (`double`), the default - value for @a number_float_t is: - - @code {.cpp} - double - @endcode - - #### Default behavior - - - The restrictions about leading zeros is not enforced in C++. Instead, - leading zeros in floating-point literals will be ignored. Internally, - the value will be stored as decimal number. For instance, the C++ - floating-point literal `01.2` will be serialized to `1.2`. During - deserialization, leading zeros yield an error. - - Not-a-number (NaN) values will be serialized to `null`. - - #### Limits - - [RFC 7159](http://rfc7159.net/rfc7159) states: - > This specification allows implementations to set limits on the range and - > precision of numbers accepted. Since software that implements IEEE - > 754-2008 binary64 (double precision) numbers is generally available and - > widely used, good interoperability can be achieved by implementations - > that expect no more precision or range than these provide, in the sense - > that implementations will approximate JSON numbers within the expected - > precision. - - This implementation does exactly follow this approach, as it uses double - precision floating-point numbers. Note values smaller than - `-1.79769313486232e+308` and values greater than `1.79769313486232e+308` - will be stored as NaN internally and be serialized to `null`. - - #### Storage - - Floating-point number values are stored directly inside a @ref basic_json - type. - - @sa @ref number_integer_t -- type for number values (integer) - - @sa @ref number_unsigned_t -- type for number values (unsigned integer) - - @since version 1.0.0 - */ - using number_float_t = NumberFloatType; - - /*! - @brief a type for a packed binary type - - This type is a type designed to carry binary data that appears in various - serialized formats, such as CBOR's Major Type 2, MessagePack's bin, and - BSON's generic binary subtype. This type is NOT a part of standard JSON and - exists solely for compatibility with these binary types. As such, it is - simply defined as an ordered sequence of zero or more byte values. - - Additionally, as an implementation detail, the subtype of the binary data is - carried around as a `std::uint8_t`, which is compatible with both of the - binary data formats that use binary subtyping, (though the specific - numbering is incompatible with each other, and it is up to the user to - translate between them). - - [CBOR's RFC 7049](https://tools.ietf.org/html/rfc7049) describes this type - as: - > Major type 2: a byte string. The string's length in bytes is represented - > following the rules for positive integers (major type 0). - - [MessagePack's documentation on the bin type - family](https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family) - describes this type as: - > Bin format family stores an byte array in 2, 3, or 5 bytes of extra bytes - > in addition to the size of the byte array. - - [BSON's specifications](http://bsonspec.org/spec.html) describe several - binary types; however, this type is intended to represent the generic binary - type which has the description: - > Generic binary subtype - This is the most commonly used binary subtype and - > should be the 'default' for drivers and tools. - - None of these impose any limitations on the internal representation other - than the basic unit of storage be some type of array whose parts are - decomposable into bytes. - - The default representation of this binary format is a - `std::vector`, which is a very common way to represent a byte - array in modern C++. - - #### Default type - - The default values for @a BinaryType is `std::vector` - - #### Storage - - Binary Arrays are stored as pointers in a @ref basic_json type. That is, - for any access to array values, a pointer of the type `binary_t*` must be - dereferenced. - - #### Notes on subtypes - - - CBOR - - Binary values are represented as byte strings. No subtypes are - supported and will be ignored when CBOR is written. - - MessagePack - - If a subtype is given and the binary array contains exactly 1, 2, 4, 8, - or 16 elements, the fixext family (fixext1, fixext2, fixext4, fixext8) - is used. For other sizes, the ext family (ext8, ext16, ext32) is used. - The subtype is then added as singed 8-bit integer. - - If no subtype is given, the bin family (bin8, bin16, bin32) is used. - - BSON - - If a subtype is given, it is used and added as unsigned 8-bit integer. - - If no subtype is given, the generic binary subtype 0x00 is used. - - @sa @ref binary -- create a binary array - - @since version 3.8.0 - */ - using binary_t = nlohmann::byte_container_with_subtype; - /// @} - - private: - - /// helper for exception-safe object creation - template - JSON_HEDLEY_RETURNS_NON_NULL - static T* create(Args&& ... args) - { - AllocatorType alloc; - using AllocatorTraits = std::allocator_traits>; - - auto deleter = [&](T * object) - { - AllocatorTraits::deallocate(alloc, object, 1); - }; - std::unique_ptr object(AllocatorTraits::allocate(alloc, 1), deleter); - AllocatorTraits::construct(alloc, object.get(), std::forward(args)...); - JSON_ASSERT(object != nullptr); - return object.release(); - } - - //////////////////////// - // JSON value storage // - //////////////////////// - - /*! - @brief a JSON value - - The actual storage for a JSON value of the @ref basic_json class. This - union combines the different storage types for the JSON value types - defined in @ref value_t. - - JSON type | value_t type | used type - --------- | --------------- | ------------------------ - object | object | pointer to @ref object_t - array | array | pointer to @ref array_t - string | string | pointer to @ref string_t - boolean | boolean | @ref boolean_t - number | number_integer | @ref number_integer_t - number | number_unsigned | @ref number_unsigned_t - number | number_float | @ref number_float_t - binary | binary | pointer to @ref binary_t - null | null | *no value is stored* - - @note Variable-length types (objects, arrays, and strings) are stored as - pointers. The size of the union should not exceed 64 bits if the default - value types are used. - - @since version 1.0.0 - */ - union json_value - { - /// object (stored with pointer to save storage) - object_t* object; - /// array (stored with pointer to save storage) - array_t* array; - /// string (stored with pointer to save storage) - string_t* string; - /// binary (stored with pointer to save storage) - binary_t* binary; - /// boolean - boolean_t boolean; - /// number (integer) - number_integer_t number_integer; - /// number (unsigned integer) - number_unsigned_t number_unsigned; - /// number (floating-point) - number_float_t number_float; - - /// default constructor (for null values) - json_value() = default; - /// constructor for booleans - json_value(boolean_t v) noexcept : boolean(v) {} - /// constructor for numbers (integer) - json_value(number_integer_t v) noexcept : number_integer(v) {} - /// constructor for numbers (unsigned) - json_value(number_unsigned_t v) noexcept : number_unsigned(v) {} - /// constructor for numbers (floating-point) - json_value(number_float_t v) noexcept : number_float(v) {} - /// constructor for empty values of a given type - json_value(value_t t) - { - switch (t) - { - case value_t::object: - { - object = create(); - break; - } - - case value_t::array: - { - array = create(); - break; - } - - case value_t::string: - { - string = create(""); - break; - } - - case value_t::binary: - { - binary = create(); - break; - } - - case value_t::boolean: - { - boolean = boolean_t(false); - break; - } - - case value_t::number_integer: - { - number_integer = number_integer_t(0); - break; - } - - case value_t::number_unsigned: - { - number_unsigned = number_unsigned_t(0); - break; - } - - case value_t::number_float: - { - number_float = number_float_t(0.0); - break; - } - - case value_t::null: - { - object = nullptr; // silence warning, see #821 - break; - } - - default: - { - object = nullptr; // silence warning, see #821 - if (JSON_HEDLEY_UNLIKELY(t == value_t::null)) - { - JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.9.1")); // LCOV_EXCL_LINE - } - break; - } - } - } - - /// constructor for strings - json_value(const string_t& value) - { - string = create(value); - } - - /// constructor for rvalue strings - json_value(string_t&& value) - { - string = create(std::move(value)); - } - - /// constructor for objects - json_value(const object_t& value) - { - object = create(value); - } - - /// constructor for rvalue objects - json_value(object_t&& value) - { - object = create(std::move(value)); - } - - /// constructor for arrays - json_value(const array_t& value) - { - array = create(value); - } - - /// constructor for rvalue arrays - json_value(array_t&& value) - { - array = create(std::move(value)); - } - - /// constructor for binary arrays - json_value(const typename binary_t::container_type& value) - { - binary = create(value); - } - - /// constructor for rvalue binary arrays - json_value(typename binary_t::container_type&& value) - { - binary = create(std::move(value)); - } - - /// constructor for binary arrays (internal type) - json_value(const binary_t& value) - { - binary = create(value); - } - - /// constructor for rvalue binary arrays (internal type) - json_value(binary_t&& value) - { - binary = create(std::move(value)); - } - - void destroy(value_t t) noexcept - { - // flatten the current json_value to a heap-allocated stack - std::vector stack; - - // move the top-level items to stack - if (t == value_t::array) - { - stack.reserve(array->size()); - std::move(array->begin(), array->end(), std::back_inserter(stack)); - } - else if (t == value_t::object) - { - stack.reserve(object->size()); - for (auto&& it : *object) - { - stack.push_back(std::move(it.second)); - } - } - - while (!stack.empty()) - { - // move the last item to local variable to be processed - basic_json current_item(std::move(stack.back())); - stack.pop_back(); - - // if current_item is array/object, move - // its children to the stack to be processed later - if (current_item.is_array()) - { - std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), - std::back_inserter(stack)); - - current_item.m_value.array->clear(); - } - else if (current_item.is_object()) - { - for (auto&& it : *current_item.m_value.object) - { - stack.push_back(std::move(it.second)); - } - - current_item.m_value.object->clear(); - } - - // it's now safe that current_item get destructed - // since it doesn't have any children - } - - switch (t) - { - case value_t::object: - { - AllocatorType alloc; - std::allocator_traits::destroy(alloc, object); - std::allocator_traits::deallocate(alloc, object, 1); - break; - } - - case value_t::array: - { - AllocatorType alloc; - std::allocator_traits::destroy(alloc, array); - std::allocator_traits::deallocate(alloc, array, 1); - break; - } - - case value_t::string: - { - AllocatorType alloc; - std::allocator_traits::destroy(alloc, string); - std::allocator_traits::deallocate(alloc, string, 1); - break; - } - - case value_t::binary: - { - AllocatorType alloc; - std::allocator_traits::destroy(alloc, binary); - std::allocator_traits::deallocate(alloc, binary, 1); - break; - } - - default: - { - break; - } - } - } - }; - - /*! - @brief checks the class invariants - - This function asserts the class invariants. It needs to be called at the - end of every constructor to make sure that created objects respect the - invariant. Furthermore, it has to be called each time the type of a JSON - value is changed, because the invariant expresses a relationship between - @a m_type and @a m_value. - */ - void assert_invariant() const noexcept - { - JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr); - JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr); - JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr); - JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr); - } - - public: - ////////////////////////// - // JSON parser callback // - ////////////////////////// - - /*! - @brief parser event types - - The parser callback distinguishes the following events: - - `object_start`: the parser read `{` and started to process a JSON object - - `key`: the parser read a key of a value in an object - - `object_end`: the parser read `}` and finished processing a JSON object - - `array_start`: the parser read `[` and started to process a JSON array - - `array_end`: the parser read `]` and finished processing a JSON array - - `value`: the parser finished reading a JSON value - - @image html callback_events.png "Example when certain parse events are triggered" - - @sa @ref parser_callback_t for more information and examples - */ - using parse_event_t = detail::parse_event_t; - - /*! - @brief per-element parser callback type - - With a parser callback function, the result of parsing a JSON text can be - influenced. When passed to @ref parse, it is called on certain events - (passed as @ref parse_event_t via parameter @a event) with a set recursion - depth @a depth and context JSON value @a parsed. The return value of the - callback function is a boolean indicating whether the element that emitted - the callback shall be kept or not. - - We distinguish six scenarios (determined by the event type) in which the - callback function can be called. The following table describes the values - of the parameters @a depth, @a event, and @a parsed. - - parameter @a event | description | parameter @a depth | parameter @a parsed - ------------------ | ----------- | ------------------ | ------------------- - parse_event_t::object_start | the parser read `{` and started to process a JSON object | depth of the parent of the JSON object | a JSON value with type discarded - parse_event_t::key | the parser read a key of a value in an object | depth of the currently parsed JSON object | a JSON string containing the key - parse_event_t::object_end | the parser read `}` and finished processing a JSON object | depth of the parent of the JSON object | the parsed JSON object - parse_event_t::array_start | the parser read `[` and started to process a JSON array | depth of the parent of the JSON array | a JSON value with type discarded - parse_event_t::array_end | the parser read `]` and finished processing a JSON array | depth of the parent of the JSON array | the parsed JSON array - parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value - - @image html callback_events.png "Example when certain parse events are triggered" - - Discarding a value (i.e., returning `false`) has different effects - depending on the context in which function was called: - - - Discarded values in structured types are skipped. That is, the parser - will behave as if the discarded value was never read. - - In case a value outside a structured type is skipped, it is replaced - with `null`. This case happens if the top-level element is skipped. - - @param[in] depth the depth of the recursion during parsing - - @param[in] event an event of type parse_event_t indicating the context in - the callback function has been called - - @param[in,out] parsed the current intermediate parse result; note that - writing to this value has no effect for parse_event_t::key events - - @return Whether the JSON value which called the function during parsing - should be kept (`true`) or not (`false`). In the latter case, it is either - skipped completely or replaced by an empty discarded object. - - @sa @ref parse for examples - - @since version 1.0.0 - */ - using parser_callback_t = detail::parser_callback_t; - - ////////////////// - // constructors // - ////////////////// - - /// @name constructors and destructors - /// Constructors of class @ref basic_json, copy/move constructor, copy - /// assignment, static functions creating objects, and the destructor. - /// @{ - - /*! - @brief create an empty value with a given type - - Create an empty JSON value with a given type. The value will be default - initialized with an empty value which depends on the type: - - Value type | initial value - ----------- | ------------- - null | `null` - boolean | `false` - string | `""` - number | `0` - object | `{}` - array | `[]` - binary | empty array - - @param[in] v the type of the value to create - - @complexity Constant. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @liveexample{The following code shows the constructor for different @ref - value_t values,basic_json__value_t} - - @sa @ref clear() -- restores the postcondition of this constructor - - @since version 1.0.0 - */ - basic_json(const value_t v) - : m_type(v), m_value(v) - { - assert_invariant(); - } - - /*! - @brief create a null object - - Create a `null` JSON value. It either takes a null pointer as parameter - (explicitly creating `null`) or no parameter (implicitly creating `null`). - The passed null pointer itself is not read -- it is only used to choose - the right constructor. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this constructor never throws - exceptions. - - @liveexample{The following code shows the constructor with and without a - null pointer parameter.,basic_json__nullptr_t} - - @since version 1.0.0 - */ - basic_json(std::nullptr_t = nullptr) noexcept - : basic_json(value_t::null) - { - assert_invariant(); - } - - /*! - @brief create a JSON value - - This is a "catch all" constructor for all compatible JSON types; that is, - types for which a `to_json()` method exists. The constructor forwards the - parameter @a val to that method (to `json_serializer::to_json` method - with `U = uncvref_t`, to be exact). - - Template type @a CompatibleType includes, but is not limited to, the - following types: - - **arrays**: @ref array_t and all kinds of compatible containers such as - `std::vector`, `std::deque`, `std::list`, `std::forward_list`, - `std::array`, `std::valarray`, `std::set`, `std::unordered_set`, - `std::multiset`, and `std::unordered_multiset` with a `value_type` from - which a @ref basic_json value can be constructed. - - **objects**: @ref object_t and all kinds of compatible associative - containers such as `std::map`, `std::unordered_map`, `std::multimap`, - and `std::unordered_multimap` with a `key_type` compatible to - @ref string_t and a `value_type` from which a @ref basic_json value can - be constructed. - - **strings**: @ref string_t, string literals, and all compatible string - containers can be used. - - **numbers**: @ref number_integer_t, @ref number_unsigned_t, - @ref number_float_t, and all convertible number types such as `int`, - `size_t`, `int64_t`, `float` or `double` can be used. - - **boolean**: @ref boolean_t / `bool` can be used. - - **binary**: @ref binary_t / `std::vector` may be used, - unfortunately because string literals cannot be distinguished from binary - character arrays by the C++ type system, all types compatible with `const - char*` will be directed to the string constructor instead. This is both - for backwards compatibility, and due to the fact that a binary type is not - a standard JSON type. - - See the examples below. - - @tparam CompatibleType a type such that: - - @a CompatibleType is not derived from `std::istream`, - - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move - constructors), - - @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments) - - @a CompatibleType is not a @ref basic_json nested type (e.g., - @ref json_pointer, @ref iterator, etc ...) - - @ref @ref json_serializer has a - `to_json(basic_json_t&, CompatibleType&&)` method - - @tparam U = `uncvref_t` - - @param[in] val the value to be forwarded to the respective constructor - - @complexity Usually linear in the size of the passed @a val, also - depending on the implementation of the called `to_json()` - method. - - @exceptionsafety Depends on the called constructor. For types directly - supported by the library (i.e., all types for which no `to_json()` function - was provided), strong guarantee holds: if an exception is thrown, there are - no changes to any JSON value. - - @liveexample{The following code shows the constructor with several - compatible types.,basic_json__CompatibleType} - - @since version 2.1.0 - */ - template < typename CompatibleType, - typename U = detail::uncvref_t, - detail::enable_if_t < - !detail::is_basic_json::value && detail::is_compatible_type::value, int > = 0 > - basic_json(CompatibleType && val) noexcept(noexcept( - JSONSerializer::to_json(std::declval(), - std::forward(val)))) - { - JSONSerializer::to_json(*this, std::forward(val)); - assert_invariant(); - } - - /*! - @brief create a JSON value from an existing one - - This is a constructor for existing @ref basic_json types. - It does not hijack copy/move constructors, since the parameter has different - template arguments than the current ones. - - The constructor tries to convert the internal @ref m_value of the parameter. - - @tparam BasicJsonType a type such that: - - @a BasicJsonType is a @ref basic_json type. - - @a BasicJsonType has different template arguments than @ref basic_json_t. - - @param[in] val the @ref basic_json value to be converted. - - @complexity Usually linear in the size of the passed @a val, also - depending on the implementation of the called `to_json()` - method. - - @exceptionsafety Depends on the called constructor. For types directly - supported by the library (i.e., all types for which no `to_json()` function - was provided), strong guarantee holds: if an exception is thrown, there are - no changes to any JSON value. - - @since version 3.2.0 - */ - template < typename BasicJsonType, - detail::enable_if_t < - detail::is_basic_json::value&& !std::is_same::value, int > = 0 > - basic_json(const BasicJsonType& val) - { - using other_boolean_t = typename BasicJsonType::boolean_t; - using other_number_float_t = typename BasicJsonType::number_float_t; - using other_number_integer_t = typename BasicJsonType::number_integer_t; - using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using other_string_t = typename BasicJsonType::string_t; - using other_object_t = typename BasicJsonType::object_t; - using other_array_t = typename BasicJsonType::array_t; - using other_binary_t = typename BasicJsonType::binary_t; - - switch (val.type()) - { - case value_t::boolean: - JSONSerializer::to_json(*this, val.template get()); - break; - case value_t::number_float: - JSONSerializer::to_json(*this, val.template get()); - break; - case value_t::number_integer: - JSONSerializer::to_json(*this, val.template get()); - break; - case value_t::number_unsigned: - JSONSerializer::to_json(*this, val.template get()); - break; - case value_t::string: - JSONSerializer::to_json(*this, val.template get_ref()); - break; - case value_t::object: - JSONSerializer::to_json(*this, val.template get_ref()); - break; - case value_t::array: - JSONSerializer::to_json(*this, val.template get_ref()); - break; - case value_t::binary: - JSONSerializer::to_json(*this, val.template get_ref()); - break; - case value_t::null: - *this = nullptr; - break; - case value_t::discarded: - m_type = value_t::discarded; - break; - default: // LCOV_EXCL_LINE - JSON_ASSERT(false); // LCOV_EXCL_LINE - } - assert_invariant(); - } - - /*! - @brief create a container (array or object) from an initializer list - - Creates a JSON value of type array or object from the passed initializer - list @a init. In case @a type_deduction is `true` (default), the type of - the JSON value to be created is deducted from the initializer list @a init - according to the following rules: - - 1. If the list is empty, an empty JSON object value `{}` is created. - 2. If the list consists of pairs whose first element is a string, a JSON - object value is created where the first elements of the pairs are - treated as keys and the second elements are as values. - 3. In all other cases, an array is created. - - The rules aim to create the best fit between a C++ initializer list and - JSON values. The rationale is as follows: - - 1. The empty initializer list is written as `{}` which is exactly an empty - JSON object. - 2. C++ has no way of describing mapped types other than to list a list of - pairs. As JSON requires that keys must be of type string, rule 2 is the - weakest constraint one can pose on initializer lists to interpret them - as an object. - 3. In all other cases, the initializer list could not be interpreted as - JSON object type, so interpreting it as JSON array type is safe. - - With the rules described above, the following JSON values cannot be - expressed by an initializer list: - - - the empty array (`[]`): use @ref array(initializer_list_t) - with an empty initializer list in this case - - arrays whose elements satisfy rule 2: use @ref - array(initializer_list_t) with the same initializer list - in this case - - @note When used without parentheses around an empty initializer list, @ref - basic_json() is called instead of this function, yielding the JSON null - value. - - @param[in] init initializer list with JSON values - - @param[in] type_deduction internal parameter; when set to `true`, the type - of the JSON value is deducted from the initializer list @a init; when set - to `false`, the type provided via @a manual_type is forced. This mode is - used by the functions @ref array(initializer_list_t) and - @ref object(initializer_list_t). - - @param[in] manual_type internal parameter; when @a type_deduction is set - to `false`, the created JSON value will use the provided type (only @ref - value_t::array and @ref value_t::object are valid); when @a type_deduction - is set to `true`, this parameter has no effect - - @throw type_error.301 if @a type_deduction is `false`, @a manual_type is - `value_t::object`, but @a init contains an element which is not a pair - whose first element is a string. In this case, the constructor could not - create an object. If @a type_deduction would have be `true`, an array - would have been created. See @ref object(initializer_list_t) - for an example. - - @complexity Linear in the size of the initializer list @a init. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @liveexample{The example below shows how JSON values are created from - initializer lists.,basic_json__list_init_t} - - @sa @ref array(initializer_list_t) -- create a JSON array - value from an initializer list - @sa @ref object(initializer_list_t) -- create a JSON object - value from an initializer list - - @since version 1.0.0 - */ - basic_json(initializer_list_t init, - bool type_deduction = true, - value_t manual_type = value_t::array) - { - // check if each element is an array with two elements whose first - // element is a string - bool is_an_object = std::all_of(init.begin(), init.end(), - [](const detail::json_ref& element_ref) - { - return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string(); - }); - - // adjust type if type deduction is not wanted - if (!type_deduction) - { - // if array is wanted, do not create an object though possible - if (manual_type == value_t::array) - { - is_an_object = false; - } - - // if object is wanted but impossible, throw an exception - if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object)) - { - JSON_THROW(type_error::create(301, "cannot create object from initializer list")); - } - } - - if (is_an_object) - { - // the initializer list is a list of pairs -> create object - m_type = value_t::object; - m_value = value_t::object; - - std::for_each(init.begin(), init.end(), [this](const detail::json_ref& element_ref) - { - auto element = element_ref.moved_or_copied(); - m_value.object->emplace( - std::move(*((*element.m_value.array)[0].m_value.string)), - std::move((*element.m_value.array)[1])); - }); - } - else - { - // the initializer list describes an array -> create array - m_type = value_t::array; - m_value.array = create(init.begin(), init.end()); - } - - assert_invariant(); - } - - /*! - @brief explicitly create a binary array (without subtype) - - Creates a JSON binary array value from a given binary container. Binary - values are part of various binary formats, such as CBOR, MessagePack, and - BSON. This constructor is used to create a value for serialization to those - formats. - - @note Note, this function exists because of the difficulty in correctly - specifying the correct template overload in the standard value ctor, as both - JSON arrays and JSON binary arrays are backed with some form of a - `std::vector`. Because JSON binary arrays are a non-standard extension it - was decided that it would be best to prevent automatic initialization of a - binary array type, for backwards compatibility and so it does not happen on - accident. - - @param[in] init container containing bytes to use as binary type - - @return JSON binary array value - - @complexity Linear in the size of @a init. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @since version 3.8.0 - */ - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json binary(const typename binary_t::container_type& init) - { - auto res = basic_json(); - res.m_type = value_t::binary; - res.m_value = init; - return res; - } - - /*! - @brief explicitly create a binary array (with subtype) - - Creates a JSON binary array value from a given binary container. Binary - values are part of various binary formats, such as CBOR, MessagePack, and - BSON. This constructor is used to create a value for serialization to those - formats. - - @note Note, this function exists because of the difficulty in correctly - specifying the correct template overload in the standard value ctor, as both - JSON arrays and JSON binary arrays are backed with some form of a - `std::vector`. Because JSON binary arrays are a non-standard extension it - was decided that it would be best to prevent automatic initialization of a - binary array type, for backwards compatibility and so it does not happen on - accident. - - @param[in] init container containing bytes to use as binary type - @param[in] subtype subtype to use in MessagePack and BSON - - @return JSON binary array value - - @complexity Linear in the size of @a init. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @since version 3.8.0 - */ - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json binary(const typename binary_t::container_type& init, std::uint8_t subtype) - { - auto res = basic_json(); - res.m_type = value_t::binary; - res.m_value = binary_t(init, subtype); - return res; - } - - /// @copydoc binary(const typename binary_t::container_type&) - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json binary(typename binary_t::container_type&& init) - { - auto res = basic_json(); - res.m_type = value_t::binary; - res.m_value = std::move(init); - return res; - } - - /// @copydoc binary(const typename binary_t::container_type&, std::uint8_t) - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json binary(typename binary_t::container_type&& init, std::uint8_t subtype) - { - auto res = basic_json(); - res.m_type = value_t::binary; - res.m_value = binary_t(std::move(init), subtype); - return res; - } - - /*! - @brief explicitly create an array from an initializer list - - Creates a JSON array value from a given initializer list. That is, given a - list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the - initializer list is empty, the empty array `[]` is created. - - @note This function is only needed to express two edge cases that cannot - be realized with the initializer list constructor (@ref - basic_json(initializer_list_t, bool, value_t)). These cases - are: - 1. creating an array whose elements are all pairs whose first element is a - string -- in this case, the initializer list constructor would create an - object, taking the first elements as keys - 2. creating an empty array -- passing the empty initializer list to the - initializer list constructor yields an empty object - - @param[in] init initializer list with JSON values to create an array from - (optional) - - @return JSON array value - - @complexity Linear in the size of @a init. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @liveexample{The following code shows an example for the `array` - function.,array} - - @sa @ref basic_json(initializer_list_t, bool, value_t) -- - create a JSON value from an initializer list - @sa @ref object(initializer_list_t) -- create a JSON object - value from an initializer list - - @since version 1.0.0 - */ - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json array(initializer_list_t init = {}) - { - return basic_json(init, false, value_t::array); - } - - /*! - @brief explicitly create an object from an initializer list - - Creates a JSON object value from a given initializer list. The initializer - lists elements must be pairs, and their first elements must be strings. If - the initializer list is empty, the empty object `{}` is created. - - @note This function is only added for symmetry reasons. In contrast to the - related function @ref array(initializer_list_t), there are - no cases which can only be expressed by this function. That is, any - initializer list @a init can also be passed to the initializer list - constructor @ref basic_json(initializer_list_t, bool, value_t). - - @param[in] init initializer list to create an object from (optional) - - @return JSON object value - - @throw type_error.301 if @a init is not a list of pairs whose first - elements are strings. In this case, no object can be created. When such a - value is passed to @ref basic_json(initializer_list_t, bool, value_t), - an array would have been created from the passed initializer list @a init. - See example below. - - @complexity Linear in the size of @a init. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @liveexample{The following code shows an example for the `object` - function.,object} - - @sa @ref basic_json(initializer_list_t, bool, value_t) -- - create a JSON value from an initializer list - @sa @ref array(initializer_list_t) -- create a JSON array - value from an initializer list - - @since version 1.0.0 - */ - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json object(initializer_list_t init = {}) - { - return basic_json(init, false, value_t::object); - } - - /*! - @brief construct an array with count copies of given value - - Constructs a JSON array value by creating @a cnt copies of a passed value. - In case @a cnt is `0`, an empty array is created. - - @param[in] cnt the number of JSON copies of @a val to create - @param[in] val the JSON value to copy - - @post `std::distance(begin(),end()) == cnt` holds. - - @complexity Linear in @a cnt. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @liveexample{The following code shows examples for the @ref - basic_json(size_type\, const basic_json&) - constructor.,basic_json__size_type_basic_json} - - @since version 1.0.0 - */ - basic_json(size_type cnt, const basic_json& val) - : m_type(value_t::array) - { - m_value.array = create(cnt, val); - assert_invariant(); - } - - /*! - @brief construct a JSON container given an iterator range - - Constructs the JSON value with the contents of the range `[first, last)`. - The semantics depends on the different types a JSON value can have: - - In case of a null type, invalid_iterator.206 is thrown. - - In case of other primitive types (number, boolean, or string), @a first - must be `begin()` and @a last must be `end()`. In this case, the value is - copied. Otherwise, invalid_iterator.204 is thrown. - - In case of structured types (array, object), the constructor behaves as - similar versions for `std::vector` or `std::map`; that is, a JSON array - or object is constructed from the values in the range. - - @tparam InputIT an input iterator type (@ref iterator or @ref - const_iterator) - - @param[in] first begin of the range to copy from (included) - @param[in] last end of the range to copy from (excluded) - - @pre Iterators @a first and @a last must be initialized. **This - precondition is enforced with an assertion (see warning).** If - assertions are switched off, a violation of this precondition yields - undefined behavior. - - @pre Range `[first, last)` is valid. Usually, this precondition cannot be - checked efficiently. Only certain edge cases are detected; see the - description of the exceptions below. A violation of this precondition - yields undefined behavior. - - @warning A precondition is enforced with a runtime assertion that will - result in calling `std::abort` if this precondition is not met. - Assertions can be disabled by defining `NDEBUG` at compile time. - See https://en.cppreference.com/w/cpp/error/assert for more - information. - - @throw invalid_iterator.201 if iterators @a first and @a last are not - compatible (i.e., do not belong to the same JSON value). In this case, - the range `[first, last)` is undefined. - @throw invalid_iterator.204 if iterators @a first and @a last belong to a - primitive type (number, boolean, or string), but @a first does not point - to the first element any more. In this case, the range `[first, last)` is - undefined. See example code below. - @throw invalid_iterator.206 if iterators @a first and @a last belong to a - null value. In this case, the range `[first, last)` is undefined. - - @complexity Linear in distance between @a first and @a last. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @liveexample{The example below shows several ways to create JSON values by - specifying a subrange with iterators.,basic_json__InputIt_InputIt} - - @since version 1.0.0 - */ - template < class InputIT, typename std::enable_if < - std::is_same::value || - std::is_same::value, int >::type = 0 > - basic_json(InputIT first, InputIT last) - { - JSON_ASSERT(first.m_object != nullptr); - JSON_ASSERT(last.m_object != nullptr); - - // make sure iterator fits the current value - if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object)) - { - JSON_THROW(invalid_iterator::create(201, "iterators are not compatible")); - } - - // copy type from first iterator - m_type = first.m_object->m_type; - - // check if iterator range is complete for primitive values - switch (m_type) - { - case value_t::boolean: - case value_t::number_float: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::string: - { - if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin() - || !last.m_it.primitive_iterator.is_end())) - { - JSON_THROW(invalid_iterator::create(204, "iterators out of range")); - } - break; - } - - default: - break; - } - - switch (m_type) - { - case value_t::number_integer: - { - m_value.number_integer = first.m_object->m_value.number_integer; - break; - } - - case value_t::number_unsigned: - { - m_value.number_unsigned = first.m_object->m_value.number_unsigned; - break; - } - - case value_t::number_float: - { - m_value.number_float = first.m_object->m_value.number_float; - break; - } - - case value_t::boolean: - { - m_value.boolean = first.m_object->m_value.boolean; - break; - } - - case value_t::string: - { - m_value = *first.m_object->m_value.string; - break; - } - - case value_t::object: - { - m_value.object = create(first.m_it.object_iterator, - last.m_it.object_iterator); - break; - } - - case value_t::array: - { - m_value.array = create(first.m_it.array_iterator, - last.m_it.array_iterator); - break; - } - - case value_t::binary: - { - m_value = *first.m_object->m_value.binary; - break; - } - - default: - JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " + - std::string(first.m_object->type_name()))); - } - - assert_invariant(); - } - - - /////////////////////////////////////// - // other constructors and destructor // - /////////////////////////////////////// - - template, - std::is_same>::value, int> = 0 > - basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {} - - /*! - @brief copy constructor - - Creates a copy of a given JSON value. - - @param[in] other the JSON value to copy - - @post `*this == other` - - @complexity Linear in the size of @a other. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is linear. - - As postcondition, it holds: `other == basic_json(other)`. - - @liveexample{The following code shows an example for the copy - constructor.,basic_json__basic_json} - - @since version 1.0.0 - */ - basic_json(const basic_json& other) - : m_type(other.m_type) - { - // check of passed value is valid - other.assert_invariant(); - - switch (m_type) - { - case value_t::object: - { - m_value = *other.m_value.object; - break; - } - - case value_t::array: - { - m_value = *other.m_value.array; - break; - } - - case value_t::string: - { - m_value = *other.m_value.string; - break; - } - - case value_t::boolean: - { - m_value = other.m_value.boolean; - break; - } - - case value_t::number_integer: - { - m_value = other.m_value.number_integer; - break; - } - - case value_t::number_unsigned: - { - m_value = other.m_value.number_unsigned; - break; - } - - case value_t::number_float: - { - m_value = other.m_value.number_float; - break; - } - - case value_t::binary: - { - m_value = *other.m_value.binary; - break; - } - - default: - break; - } - - assert_invariant(); - } - - /*! - @brief move constructor - - Move constructor. Constructs a JSON value with the contents of the given - value @a other using move semantics. It "steals" the resources from @a - other and leaves it as JSON null value. - - @param[in,out] other value to move to this object - - @post `*this` has the same value as @a other before the call. - @post @a other is a JSON null value. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this constructor never throws - exceptions. - - @requirement This function helps `basic_json` satisfying the - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible) - requirements. - - @liveexample{The code below shows the move constructor explicitly called - via std::move.,basic_json__moveconstructor} - - @since version 1.0.0 - */ - basic_json(basic_json&& other) noexcept - : m_type(std::move(other.m_type)), - m_value(std::move(other.m_value)) - { - // check that passed value is valid - other.assert_invariant(); - - // invalidate payload - other.m_type = value_t::null; - other.m_value = {}; - - assert_invariant(); - } - - /*! - @brief copy assignment - - Copy assignment operator. Copies a JSON value via the "copy and swap" - strategy: It is expressed in terms of the copy constructor, destructor, - and the `swap()` member function. - - @param[in] other value to copy from - - @complexity Linear. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is linear. - - @liveexample{The code below shows and example for the copy assignment. It - creates a copy of value `a` which is then swapped with `b`. Finally\, the - copy of `a` (which is the null value after the swap) is - destroyed.,basic_json__copyassignment} - - @since version 1.0.0 - */ - basic_json& operator=(basic_json other) noexcept ( - std::is_nothrow_move_constructible::value&& - std::is_nothrow_move_assignable::value&& - std::is_nothrow_move_constructible::value&& - std::is_nothrow_move_assignable::value - ) - { - // check that passed value is valid - other.assert_invariant(); - - using std::swap; - swap(m_type, other.m_type); - swap(m_value, other.m_value); - - assert_invariant(); - return *this; - } - - /*! - @brief destructor - - Destroys the JSON value and frees all allocated memory. - - @complexity Linear. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is linear. - - All stored elements are destroyed and all memory is freed. - - @since version 1.0.0 - */ - ~basic_json() noexcept - { - assert_invariant(); - m_value.destroy(m_type); - } - - /// @} - - public: - /////////////////////// - // object inspection // - /////////////////////// - - /// @name object inspection - /// Functions to inspect the type of a JSON value. - /// @{ - - /*! - @brief serialization - - Serialization function for JSON values. The function tries to mimic - Python's `json.dumps()` function, and currently supports its @a indent - and @a ensure_ascii parameters. - - @param[in] indent If indent is nonnegative, then array elements and object - members will be pretty-printed with that indent level. An indent level of - `0` will only insert newlines. `-1` (the default) selects the most compact - representation. - @param[in] indent_char The character to use for indentation if @a indent is - greater than `0`. The default is ` ` (space). - @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters - in the output are escaped with `\uXXXX` sequences, and the result consists - of ASCII characters only. - @param[in] error_handler how to react on decoding errors; there are three - possible values: `strict` (throws and exception in case a decoding error - occurs; default), `replace` (replace invalid UTF-8 sequences with U+FFFD), - and `ignore` (ignore invalid UTF-8 sequences during serialization; all - bytes are copied to the output unchanged). - - @return string containing the serialization of the JSON value - - @throw type_error.316 if a string stored inside the JSON value is not - UTF-8 encoded and @a error_handler is set to strict - - @note Binary values are serialized as object containing two keys: - - "bytes": an array of bytes as integers - - "subtype": the subtype as integer or "null" if the binary has no subtype - - @complexity Linear. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @liveexample{The following example shows the effect of different @a indent\, - @a indent_char\, and @a ensure_ascii parameters to the result of the - serialization.,dump} - - @see https://docs.python.org/2/library/json.html#json.dump - - @since version 1.0.0; indentation character @a indent_char, option - @a ensure_ascii and exceptions added in version 3.0.0; error - handlers added in version 3.4.0; serialization of binary values added - in version 3.8.0. - */ - string_t dump(const int indent = -1, - const char indent_char = ' ', - const bool ensure_ascii = false, - const error_handler_t error_handler = error_handler_t::strict) const - { - string_t result; - serializer s(detail::output_adapter(result), indent_char, error_handler); - - if (indent >= 0) - { - s.dump(*this, true, ensure_ascii, static_cast(indent)); - } - else - { - s.dump(*this, false, ensure_ascii, 0); - } - - return result; - } - - /*! - @brief return the type of the JSON value (explicit) - - Return the type of the JSON value as a value from the @ref value_t - enumeration. - - @return the type of the JSON value - Value type | return value - ------------------------- | ------------------------- - null | value_t::null - boolean | value_t::boolean - string | value_t::string - number (integer) | value_t::number_integer - number (unsigned integer) | value_t::number_unsigned - number (floating-point) | value_t::number_float - object | value_t::object - array | value_t::array - binary | value_t::binary - discarded | value_t::discarded - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `type()` for all JSON - types.,type} - - @sa @ref operator value_t() -- return the type of the JSON value (implicit) - @sa @ref type_name() -- return the type as string - - @since version 1.0.0 - */ - constexpr value_t type() const noexcept - { - return m_type; - } - - /*! - @brief return whether type is primitive - - This function returns true if and only if the JSON type is primitive - (string, number, boolean, or null). - - @return `true` if type is primitive (string, number, boolean, or null), - `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_primitive()` for all JSON - types.,is_primitive} - - @sa @ref is_structured() -- returns whether JSON value is structured - @sa @ref is_null() -- returns whether JSON value is `null` - @sa @ref is_string() -- returns whether JSON value is a string - @sa @ref is_boolean() -- returns whether JSON value is a boolean - @sa @ref is_number() -- returns whether JSON value is a number - @sa @ref is_binary() -- returns whether JSON value is a binary array - - @since version 1.0.0 - */ - constexpr bool is_primitive() const noexcept - { - return is_null() || is_string() || is_boolean() || is_number() || is_binary(); - } - - /*! - @brief return whether type is structured - - This function returns true if and only if the JSON type is structured - (array or object). - - @return `true` if type is structured (array or object), `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_structured()` for all JSON - types.,is_structured} - - @sa @ref is_primitive() -- returns whether value is primitive - @sa @ref is_array() -- returns whether value is an array - @sa @ref is_object() -- returns whether value is an object - - @since version 1.0.0 - */ - constexpr bool is_structured() const noexcept - { - return is_array() || is_object(); - } - - /*! - @brief return whether value is null - - This function returns true if and only if the JSON value is null. - - @return `true` if type is null, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_null()` for all JSON - types.,is_null} - - @since version 1.0.0 - */ - constexpr bool is_null() const noexcept - { - return m_type == value_t::null; - } - - /*! - @brief return whether value is a boolean - - This function returns true if and only if the JSON value is a boolean. - - @return `true` if type is boolean, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_boolean()` for all JSON - types.,is_boolean} - - @since version 1.0.0 - */ - constexpr bool is_boolean() const noexcept - { - return m_type == value_t::boolean; - } - - /*! - @brief return whether value is a number - - This function returns true if and only if the JSON value is a number. This - includes both integer (signed and unsigned) and floating-point values. - - @return `true` if type is number (regardless whether integer, unsigned - integer or floating-type), `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_number()` for all JSON - types.,is_number} - - @sa @ref is_number_integer() -- check if value is an integer or unsigned - integer number - @sa @ref is_number_unsigned() -- check if value is an unsigned integer - number - @sa @ref is_number_float() -- check if value is a floating-point number - - @since version 1.0.0 - */ - constexpr bool is_number() const noexcept - { - return is_number_integer() || is_number_float(); - } - - /*! - @brief return whether value is an integer number - - This function returns true if and only if the JSON value is a signed or - unsigned integer number. This excludes floating-point values. - - @return `true` if type is an integer or unsigned integer number, `false` - otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_number_integer()` for all - JSON types.,is_number_integer} - - @sa @ref is_number() -- check if value is a number - @sa @ref is_number_unsigned() -- check if value is an unsigned integer - number - @sa @ref is_number_float() -- check if value is a floating-point number - - @since version 1.0.0 - */ - constexpr bool is_number_integer() const noexcept - { - return m_type == value_t::number_integer || m_type == value_t::number_unsigned; - } - - /*! - @brief return whether value is an unsigned integer number - - This function returns true if and only if the JSON value is an unsigned - integer number. This excludes floating-point and signed integer values. - - @return `true` if type is an unsigned integer number, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_number_unsigned()` for all - JSON types.,is_number_unsigned} - - @sa @ref is_number() -- check if value is a number - @sa @ref is_number_integer() -- check if value is an integer or unsigned - integer number - @sa @ref is_number_float() -- check if value is a floating-point number - - @since version 2.0.0 - */ - constexpr bool is_number_unsigned() const noexcept - { - return m_type == value_t::number_unsigned; - } - - /*! - @brief return whether value is a floating-point number - - This function returns true if and only if the JSON value is a - floating-point number. This excludes signed and unsigned integer values. - - @return `true` if type is a floating-point number, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_number_float()` for all - JSON types.,is_number_float} - - @sa @ref is_number() -- check if value is number - @sa @ref is_number_integer() -- check if value is an integer number - @sa @ref is_number_unsigned() -- check if value is an unsigned integer - number - - @since version 1.0.0 - */ - constexpr bool is_number_float() const noexcept - { - return m_type == value_t::number_float; - } - - /*! - @brief return whether value is an object - - This function returns true if and only if the JSON value is an object. - - @return `true` if type is object, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_object()` for all JSON - types.,is_object} - - @since version 1.0.0 - */ - constexpr bool is_object() const noexcept - { - return m_type == value_t::object; - } - - /*! - @brief return whether value is an array - - This function returns true if and only if the JSON value is an array. - - @return `true` if type is array, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_array()` for all JSON - types.,is_array} - - @since version 1.0.0 - */ - constexpr bool is_array() const noexcept - { - return m_type == value_t::array; - } - - /*! - @brief return whether value is a string - - This function returns true if and only if the JSON value is a string. - - @return `true` if type is string, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_string()` for all JSON - types.,is_string} - - @since version 1.0.0 - */ - constexpr bool is_string() const noexcept - { - return m_type == value_t::string; - } - - /*! - @brief return whether value is a binary array - - This function returns true if and only if the JSON value is a binary array. - - @return `true` if type is binary array, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_binary()` for all JSON - types.,is_binary} - - @since version 3.8.0 - */ - constexpr bool is_binary() const noexcept - { - return m_type == value_t::binary; - } - - /*! - @brief return whether value is discarded - - This function returns true if and only if the JSON value was discarded - during parsing with a callback function (see @ref parser_callback_t). - - @note This function will always be `false` for JSON values after parsing. - That is, discarded values can only occur during parsing, but will be - removed when inside a structured value or replaced by null in other cases. - - @return `true` if type is discarded, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_discarded()` for all JSON - types.,is_discarded} - - @since version 1.0.0 - */ - constexpr bool is_discarded() const noexcept - { - return m_type == value_t::discarded; - } - - /*! - @brief return the type of the JSON value (implicit) - - Implicitly return the type of the JSON value as a value from the @ref - value_t enumeration. - - @return the type of the JSON value - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies the @ref value_t operator for - all JSON types.,operator__value_t} - - @sa @ref type() -- return the type of the JSON value (explicit) - @sa @ref type_name() -- return the type as string - - @since version 1.0.0 - */ - constexpr operator value_t() const noexcept - { - return m_type; - } - - /// @} - - private: - ////////////////// - // value access // - ////////////////// - - /// get a boolean (explicit) - boolean_t get_impl(boolean_t* /*unused*/) const - { - if (JSON_HEDLEY_LIKELY(is_boolean())) - { - return m_value.boolean; - } - - JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name()))); - } - - /// get a pointer to the value (object) - object_t* get_impl_ptr(object_t* /*unused*/) noexcept - { - return is_object() ? m_value.object : nullptr; - } - - /// get a pointer to the value (object) - constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept - { - return is_object() ? m_value.object : nullptr; - } - - /// get a pointer to the value (array) - array_t* get_impl_ptr(array_t* /*unused*/) noexcept - { - return is_array() ? m_value.array : nullptr; - } - - /// get a pointer to the value (array) - constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept - { - return is_array() ? m_value.array : nullptr; - } - - /// get a pointer to the value (string) - string_t* get_impl_ptr(string_t* /*unused*/) noexcept - { - return is_string() ? m_value.string : nullptr; - } - - /// get a pointer to the value (string) - constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept - { - return is_string() ? m_value.string : nullptr; - } - - /// get a pointer to the value (boolean) - boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept - { - return is_boolean() ? &m_value.boolean : nullptr; - } - - /// get a pointer to the value (boolean) - constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept - { - return is_boolean() ? &m_value.boolean : nullptr; - } - - /// get a pointer to the value (integer number) - number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept - { - return is_number_integer() ? &m_value.number_integer : nullptr; - } - - /// get a pointer to the value (integer number) - constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept - { - return is_number_integer() ? &m_value.number_integer : nullptr; - } - - /// get a pointer to the value (unsigned number) - number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept - { - return is_number_unsigned() ? &m_value.number_unsigned : nullptr; - } - - /// get a pointer to the value (unsigned number) - constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept - { - return is_number_unsigned() ? &m_value.number_unsigned : nullptr; - } - - /// get a pointer to the value (floating-point number) - number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept - { - return is_number_float() ? &m_value.number_float : nullptr; - } - - /// get a pointer to the value (floating-point number) - constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept - { - return is_number_float() ? &m_value.number_float : nullptr; - } - - /// get a pointer to the value (binary) - binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept - { - return is_binary() ? m_value.binary : nullptr; - } - - /// get a pointer to the value (binary) - constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept - { - return is_binary() ? m_value.binary : nullptr; - } - - /*! - @brief helper function to implement get_ref() - - This function helps to implement get_ref() without code duplication for - const and non-const overloads - - @tparam ThisType will be deduced as `basic_json` or `const basic_json` - - @throw type_error.303 if ReferenceType does not match underlying value - type of the current JSON - */ - template - static ReferenceType get_ref_impl(ThisType& obj) - { - // delegate the call to get_ptr<>() - auto ptr = obj.template get_ptr::type>(); - - if (JSON_HEDLEY_LIKELY(ptr != nullptr)) - { - return *ptr; - } - - JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name()))); - } - - public: - /// @name value access - /// Direct access to the stored value of a JSON value. - /// @{ - - /*! - @brief get special-case overload - - This overloads avoids a lot of template boilerplate, it can be seen as the - identity method - - @tparam BasicJsonType == @ref basic_json - - @return a copy of *this - - @complexity Constant. - - @since version 2.1.0 - */ - template::type, basic_json_t>::value, - int> = 0> - basic_json get() const - { - return *this; - } - - /*! - @brief get special-case overload - - This overloads converts the current @ref basic_json in a different - @ref basic_json type - - @tparam BasicJsonType == @ref basic_json - - @return a copy of *this, converted into @tparam BasicJsonType - - @complexity Depending on the implementation of the called `from_json()` - method. - - @since version 3.2.0 - */ - template < typename BasicJsonType, detail::enable_if_t < - !std::is_same::value&& - detail::is_basic_json::value, int > = 0 > - BasicJsonType get() const - { - return *this; - } - - /*! - @brief get a value (explicit) - - Explicit type conversion between the JSON value and a compatible value - which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible) - and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). - The value is converted by calling the @ref json_serializer - `from_json()` method. - - The function is equivalent to executing - @code {.cpp} - ValueType ret; - JSONSerializer::from_json(*this, ret); - return ret; - @endcode - - This overloads is chosen if: - - @a ValueType is not @ref basic_json, - - @ref json_serializer has a `from_json()` method of the form - `void from_json(const basic_json&, ValueType&)`, and - - @ref json_serializer does not have a `from_json()` method of - the form `ValueType from_json(const basic_json&)` - - @tparam ValueTypeCV the provided value type - @tparam ValueType the returned value type - - @return copy of the JSON value, converted to @a ValueType - - @throw what @ref json_serializer `from_json()` method throws - - @liveexample{The example below shows several conversions from JSON values - to other types. There a few things to note: (1) Floating-point numbers can - be converted to integers\, (2) A JSON array can be converted to a standard - `std::vector`\, (3) A JSON object can be converted to C++ - associative containers such as `std::unordered_map`.,get__ValueType_const} - - @since version 2.1.0 - */ - template < typename ValueTypeCV, typename ValueType = detail::uncvref_t, - detail::enable_if_t < - !detail::is_basic_json::value && - detail::has_from_json::value && - !detail::has_non_default_from_json::value, - int > = 0 > - ValueType get() const noexcept(noexcept( - JSONSerializer::from_json(std::declval(), std::declval()))) - { - // we cannot static_assert on ValueTypeCV being non-const, because - // there is support for get(), which is why we - // still need the uncvref - static_assert(!std::is_reference::value, - "get() cannot be used with reference types, you might want to use get_ref()"); - static_assert(std::is_default_constructible::value, - "types must be DefaultConstructible when used with get()"); - - ValueType ret; - JSONSerializer::from_json(*this, ret); - return ret; - } - - /*! - @brief get a value (explicit); special case - - Explicit type conversion between the JSON value and a compatible value - which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible) - and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). - The value is converted by calling the @ref json_serializer - `from_json()` method. - - The function is equivalent to executing - @code {.cpp} - return JSONSerializer::from_json(*this); - @endcode - - This overloads is chosen if: - - @a ValueType is not @ref basic_json and - - @ref json_serializer has a `from_json()` method of the form - `ValueType from_json(const basic_json&)` - - @note If @ref json_serializer has both overloads of - `from_json()`, this one is chosen. - - @tparam ValueTypeCV the provided value type - @tparam ValueType the returned value type - - @return copy of the JSON value, converted to @a ValueType - - @throw what @ref json_serializer `from_json()` method throws - - @since version 2.1.0 - */ - template < typename ValueTypeCV, typename ValueType = detail::uncvref_t, - detail::enable_if_t < !std::is_same::value && - detail::has_non_default_from_json::value, - int > = 0 > - ValueType get() const noexcept(noexcept( - JSONSerializer::from_json(std::declval()))) - { - static_assert(!std::is_reference::value, - "get() cannot be used with reference types, you might want to use get_ref()"); - return JSONSerializer::from_json(*this); - } - - /*! - @brief get a value (explicit) - - Explicit type conversion between the JSON value and a compatible value. - The value is filled into the input parameter by calling the @ref json_serializer - `from_json()` method. - - The function is equivalent to executing - @code {.cpp} - ValueType v; - JSONSerializer::from_json(*this, v); - @endcode - - This overloads is chosen if: - - @a ValueType is not @ref basic_json, - - @ref json_serializer has a `from_json()` method of the form - `void from_json(const basic_json&, ValueType&)`, and - - @tparam ValueType the input parameter type. - - @return the input parameter, allowing chaining calls. - - @throw what @ref json_serializer `from_json()` method throws - - @liveexample{The example below shows several conversions from JSON values - to other types. There a few things to note: (1) Floating-point numbers can - be converted to integers\, (2) A JSON array can be converted to a standard - `std::vector`\, (3) A JSON object can be converted to C++ - associative containers such as `std::unordered_map`.,get_to} - - @since version 3.3.0 - */ - template < typename ValueType, - detail::enable_if_t < - !detail::is_basic_json::value&& - detail::has_from_json::value, - int > = 0 > - ValueType & get_to(ValueType& v) const noexcept(noexcept( - JSONSerializer::from_json(std::declval(), v))) - { - JSONSerializer::from_json(*this, v); - return v; - } - - // specialization to allow to call get_to with a basic_json value - // see https://github.com/nlohmann/json/issues/2175 - template::value, - int> = 0> - ValueType & get_to(ValueType& v) const - { - v = *this; - return v; - } - - template < - typename T, std::size_t N, - typename Array = T (&)[N], - detail::enable_if_t < - detail::has_from_json::value, int > = 0 > - Array get_to(T (&v)[N]) const - noexcept(noexcept(JSONSerializer::from_json( - std::declval(), v))) - { - JSONSerializer::from_json(*this, v); - return v; - } - - - /*! - @brief get a pointer value (implicit) - - Implicit pointer access to the internally stored JSON value. No copies are - made. - - @warning Writing data to the pointee of the result yields an undefined - state. - - @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref - object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, - @ref number_unsigned_t, or @ref number_float_t. Enforced by a static - assertion. - - @return pointer to the internally stored JSON value if the requested - pointer type @a PointerType fits to the JSON value; `nullptr` otherwise - - @complexity Constant. - - @liveexample{The example below shows how pointers to internal values of a - JSON value can be requested. Note that no type conversions are made and a - `nullptr` is returned if the value and the requested pointer type does not - match.,get_ptr} - - @since version 1.0.0 - */ - template::value, int>::type = 0> - auto get_ptr() noexcept -> decltype(std::declval().get_impl_ptr(std::declval())) - { - // delegate the call to get_impl_ptr<>() - return get_impl_ptr(static_cast(nullptr)); - } - - /*! - @brief get a pointer value (implicit) - @copydoc get_ptr() - */ - template < typename PointerType, typename std::enable_if < - std::is_pointer::value&& - std::is_const::type>::value, int >::type = 0 > - constexpr auto get_ptr() const noexcept -> decltype(std::declval().get_impl_ptr(std::declval())) - { - // delegate the call to get_impl_ptr<>() const - return get_impl_ptr(static_cast(nullptr)); - } - - /*! - @brief get a pointer value (explicit) - - Explicit pointer access to the internally stored JSON value. No copies are - made. - - @warning The pointer becomes invalid if the underlying JSON object - changes. - - @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref - object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, - @ref number_unsigned_t, or @ref number_float_t. - - @return pointer to the internally stored JSON value if the requested - pointer type @a PointerType fits to the JSON value; `nullptr` otherwise - - @complexity Constant. - - @liveexample{The example below shows how pointers to internal values of a - JSON value can be requested. Note that no type conversions are made and a - `nullptr` is returned if the value and the requested pointer type does not - match.,get__PointerType} - - @sa @ref get_ptr() for explicit pointer-member access - - @since version 1.0.0 - */ - template::value, int>::type = 0> - auto get() noexcept -> decltype(std::declval().template get_ptr()) - { - // delegate the call to get_ptr - return get_ptr(); - } - - /*! - @brief get a pointer value (explicit) - @copydoc get() - */ - template::value, int>::type = 0> - constexpr auto get() const noexcept -> decltype(std::declval().template get_ptr()) - { - // delegate the call to get_ptr - return get_ptr(); - } - - /*! - @brief get a reference value (implicit) - - Implicit reference access to the internally stored JSON value. No copies - are made. - - @warning Writing data to the referee of the result yields an undefined - state. - - @tparam ReferenceType reference type; must be a reference to @ref array_t, - @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or - @ref number_float_t. Enforced by static assertion. - - @return reference to the internally stored JSON value if the requested - reference type @a ReferenceType fits to the JSON value; throws - type_error.303 otherwise - - @throw type_error.303 in case passed type @a ReferenceType is incompatible - with the stored JSON value; see example below - - @complexity Constant. - - @liveexample{The example shows several calls to `get_ref()`.,get_ref} - - @since version 1.1.0 - */ - template::value, int>::type = 0> - ReferenceType get_ref() - { - // delegate call to get_ref_impl - return get_ref_impl(*this); - } - - /*! - @brief get a reference value (implicit) - @copydoc get_ref() - */ - template < typename ReferenceType, typename std::enable_if < - std::is_reference::value&& - std::is_const::type>::value, int >::type = 0 > - ReferenceType get_ref() const - { - // delegate call to get_ref_impl - return get_ref_impl(*this); - } - - /*! - @brief get a value (implicit) - - Implicit type conversion between the JSON value and a compatible value. - The call is realized by calling @ref get() const. - - @tparam ValueType non-pointer type compatible to the JSON value, for - instance `int` for JSON integer numbers, `bool` for JSON booleans, or - `std::vector` types for JSON arrays. The character type of @ref string_t - as well as an initializer list of this type is excluded to avoid - ambiguities as these types implicitly convert to `std::string`. - - @return copy of the JSON value, converted to type @a ValueType - - @throw type_error.302 in case passed type @a ValueType is incompatible - to the JSON value type (e.g., the JSON value is of type boolean, but a - string is requested); see example below - - @complexity Linear in the size of the JSON value. - - @liveexample{The example below shows several conversions from JSON values - to other types. There a few things to note: (1) Floating-point numbers can - be converted to integers\, (2) A JSON array can be converted to a standard - `std::vector`\, (3) A JSON object can be converted to C++ - associative containers such as `std::unordered_map`.,operator__ValueType} - - @since version 1.0.0 - */ - template < typename ValueType, typename std::enable_if < - !std::is_pointer::value&& - !std::is_same>::value&& - !std::is_same::value&& - !detail::is_basic_json::value - && !std::is_same>::value -#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914)) - && !std::is_same::value -#endif - && detail::is_detected::value - , int >::type = 0 > - JSON_EXPLICIT operator ValueType() const - { - // delegate the call to get<>() const - return get(); - } - - /*! - @return reference to the binary value - - @throw type_error.302 if the value is not binary - - @sa @ref is_binary() to check if the value is binary - - @since version 3.8.0 - */ - binary_t& get_binary() - { - if (!is_binary()) - { - JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()))); - } - - return *get_ptr(); - } - - /// @copydoc get_binary() - const binary_t& get_binary() const - { - if (!is_binary()) - { - JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()))); - } - - return *get_ptr(); - } - - /// @} - - - //////////////////// - // element access // - //////////////////// - - /// @name element access - /// Access to the JSON value. - /// @{ - - /*! - @brief access specified array element with bounds checking - - Returns a reference to the element at specified location @a idx, with - bounds checking. - - @param[in] idx index of the element to access - - @return reference to the element at index @a idx - - @throw type_error.304 if the JSON value is not an array; in this case, - calling `at` with an index makes no sense. See example below. - @throw out_of_range.401 if the index @a idx is out of range of the array; - that is, `idx >= size()`. See example below. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Constant. - - @since version 1.0.0 - - @liveexample{The example below shows how array elements can be read and - written using `at()`. It also demonstrates the different exceptions that - can be thrown.,at__size_type} - */ - reference at(size_type idx) - { - // at only works for arrays - if (JSON_HEDLEY_LIKELY(is_array())) - { - JSON_TRY - { - return m_value.array->at(idx); - } - JSON_CATCH (std::out_of_range&) - { - // create better exception explanation - JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range")); - } - } - else - { - JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()))); - } - } - - /*! - @brief access specified array element with bounds checking - - Returns a const reference to the element at specified location @a idx, - with bounds checking. - - @param[in] idx index of the element to access - - @return const reference to the element at index @a idx - - @throw type_error.304 if the JSON value is not an array; in this case, - calling `at` with an index makes no sense. See example below. - @throw out_of_range.401 if the index @a idx is out of range of the array; - that is, `idx >= size()`. See example below. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Constant. - - @since version 1.0.0 - - @liveexample{The example below shows how array elements can be read using - `at()`. It also demonstrates the different exceptions that can be thrown., - at__size_type_const} - */ - const_reference at(size_type idx) const - { - // at only works for arrays - if (JSON_HEDLEY_LIKELY(is_array())) - { - JSON_TRY - { - return m_value.array->at(idx); - } - JSON_CATCH (std::out_of_range&) - { - // create better exception explanation - JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range")); - } - } - else - { - JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()))); - } - } - - /*! - @brief access specified object element with bounds checking - - Returns a reference to the element at with specified key @a key, with - bounds checking. - - @param[in] key key of the element to access - - @return reference to the element at key @a key - - @throw type_error.304 if the JSON value is not an object; in this case, - calling `at` with a key makes no sense. See example below. - @throw out_of_range.403 if the key @a key is is not stored in the object; - that is, `find(key) == end()`. See example below. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Logarithmic in the size of the container. - - @sa @ref operator[](const typename object_t::key_type&) for unchecked - access by reference - @sa @ref value() for access by value with a default value - - @since version 1.0.0 - - @liveexample{The example below shows how object elements can be read and - written using `at()`. It also demonstrates the different exceptions that - can be thrown.,at__object_t_key_type} - */ - reference at(const typename object_t::key_type& key) - { - // at only works for objects - if (JSON_HEDLEY_LIKELY(is_object())) - { - JSON_TRY - { - return m_value.object->at(key); - } - JSON_CATCH (std::out_of_range&) - { - // create better exception explanation - JSON_THROW(out_of_range::create(403, "key '" + key + "' not found")); - } - } - else - { - JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()))); - } - } - - /*! - @brief access specified object element with bounds checking - - Returns a const reference to the element at with specified key @a key, - with bounds checking. - - @param[in] key key of the element to access - - @return const reference to the element at key @a key - - @throw type_error.304 if the JSON value is not an object; in this case, - calling `at` with a key makes no sense. See example below. - @throw out_of_range.403 if the key @a key is is not stored in the object; - that is, `find(key) == end()`. See example below. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Logarithmic in the size of the container. - - @sa @ref operator[](const typename object_t::key_type&) for unchecked - access by reference - @sa @ref value() for access by value with a default value - - @since version 1.0.0 - - @liveexample{The example below shows how object elements can be read using - `at()`. It also demonstrates the different exceptions that can be thrown., - at__object_t_key_type_const} - */ - const_reference at(const typename object_t::key_type& key) const - { - // at only works for objects - if (JSON_HEDLEY_LIKELY(is_object())) - { - JSON_TRY - { - return m_value.object->at(key); - } - JSON_CATCH (std::out_of_range&) - { - // create better exception explanation - JSON_THROW(out_of_range::create(403, "key '" + key + "' not found")); - } - } - else - { - JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()))); - } - } - - /*! - @brief access specified array element - - Returns a reference to the element at specified location @a idx. - - @note If @a idx is beyond the range of the array (i.e., `idx >= size()`), - then the array is silently filled up with `null` values to make `idx` a - valid reference to the last stored element. - - @param[in] idx index of the element to access - - @return reference to the element at index @a idx - - @throw type_error.305 if the JSON value is not an array or null; in that - cases, using the [] operator with an index makes no sense. - - @complexity Constant if @a idx is in the range of the array. Otherwise - linear in `idx - size()`. - - @liveexample{The example below shows how array elements can be read and - written using `[]` operator. Note the addition of `null` - values.,operatorarray__size_type} - - @since version 1.0.0 - */ - reference operator[](size_type idx) - { - // implicitly convert null value to an empty array - if (is_null()) - { - m_type = value_t::array; - m_value.array = create(); - assert_invariant(); - } - - // operator[] only works for arrays - if (JSON_HEDLEY_LIKELY(is_array())) - { - // fill up array with null values if given idx is outside range - if (idx >= m_value.array->size()) - { - m_value.array->insert(m_value.array->end(), - idx - m_value.array->size() + 1, - basic_json()); - } - - return m_value.array->operator[](idx); - } - - JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()))); - } - - /*! - @brief access specified array element - - Returns a const reference to the element at specified location @a idx. - - @param[in] idx index of the element to access - - @return const reference to the element at index @a idx - - @throw type_error.305 if the JSON value is not an array; in that case, - using the [] operator with an index makes no sense. - - @complexity Constant. - - @liveexample{The example below shows how array elements can be read using - the `[]` operator.,operatorarray__size_type_const} - - @since version 1.0.0 - */ - const_reference operator[](size_type idx) const - { - // const operator[] only works for arrays - if (JSON_HEDLEY_LIKELY(is_array())) - { - return m_value.array->operator[](idx); - } - - JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()))); - } - - /*! - @brief access specified object element - - Returns a reference to the element at with specified key @a key. - - @note If @a key is not found in the object, then it is silently added to - the object and filled with a `null` value to make `key` a valid reference. - In case the value was `null` before, it is converted to an object. - - @param[in] key key of the element to access - - @return reference to the element at key @a key - - @throw type_error.305 if the JSON value is not an object or null; in that - cases, using the [] operator with a key makes no sense. - - @complexity Logarithmic in the size of the container. - - @liveexample{The example below shows how object elements can be read and - written using the `[]` operator.,operatorarray__key_type} - - @sa @ref at(const typename object_t::key_type&) for access by reference - with range checking - @sa @ref value() for access by value with a default value - - @since version 1.0.0 - */ - reference operator[](const typename object_t::key_type& key) - { - // implicitly convert null value to an empty object - if (is_null()) - { - m_type = value_t::object; - m_value.object = create(); - assert_invariant(); - } - - // operator[] only works for objects - if (JSON_HEDLEY_LIKELY(is_object())) - { - return m_value.object->operator[](key); - } - - JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()))); - } - - /*! - @brief read-only access specified object element - - Returns a const reference to the element at with specified key @a key. No - bounds checking is performed. - - @warning If the element with key @a key does not exist, the behavior is - undefined. - - @param[in] key key of the element to access - - @return const reference to the element at key @a key - - @pre The element with key @a key must exist. **This precondition is - enforced with an assertion.** - - @throw type_error.305 if the JSON value is not an object; in that case, - using the [] operator with a key makes no sense. - - @complexity Logarithmic in the size of the container. - - @liveexample{The example below shows how object elements can be read using - the `[]` operator.,operatorarray__key_type_const} - - @sa @ref at(const typename object_t::key_type&) for access by reference - with range checking - @sa @ref value() for access by value with a default value - - @since version 1.0.0 - */ - const_reference operator[](const typename object_t::key_type& key) const - { - // const operator[] only works for objects - if (JSON_HEDLEY_LIKELY(is_object())) - { - JSON_ASSERT(m_value.object->find(key) != m_value.object->end()); - return m_value.object->find(key)->second; - } - - JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()))); - } - - /*! - @brief access specified object element - - Returns a reference to the element at with specified key @a key. - - @note If @a key is not found in the object, then it is silently added to - the object and filled with a `null` value to make `key` a valid reference. - In case the value was `null` before, it is converted to an object. - - @param[in] key key of the element to access - - @return reference to the element at key @a key - - @throw type_error.305 if the JSON value is not an object or null; in that - cases, using the [] operator with a key makes no sense. - - @complexity Logarithmic in the size of the container. - - @liveexample{The example below shows how object elements can be read and - written using the `[]` operator.,operatorarray__key_type} - - @sa @ref at(const typename object_t::key_type&) for access by reference - with range checking - @sa @ref value() for access by value with a default value - - @since version 1.1.0 - */ - template - JSON_HEDLEY_NON_NULL(2) - reference operator[](T* key) - { - // implicitly convert null to object - if (is_null()) - { - m_type = value_t::object; - m_value = value_t::object; - assert_invariant(); - } - - // at only works for objects - if (JSON_HEDLEY_LIKELY(is_object())) - { - return m_value.object->operator[](key); - } - - JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()))); - } - - /*! - @brief read-only access specified object element - - Returns a const reference to the element at with specified key @a key. No - bounds checking is performed. - - @warning If the element with key @a key does not exist, the behavior is - undefined. - - @param[in] key key of the element to access - - @return const reference to the element at key @a key - - @pre The element with key @a key must exist. **This precondition is - enforced with an assertion.** - - @throw type_error.305 if the JSON value is not an object; in that case, - using the [] operator with a key makes no sense. - - @complexity Logarithmic in the size of the container. - - @liveexample{The example below shows how object elements can be read using - the `[]` operator.,operatorarray__key_type_const} - - @sa @ref at(const typename object_t::key_type&) for access by reference - with range checking - @sa @ref value() for access by value with a default value - - @since version 1.1.0 - */ - template - JSON_HEDLEY_NON_NULL(2) - const_reference operator[](T* key) const - { - // at only works for objects - if (JSON_HEDLEY_LIKELY(is_object())) - { - JSON_ASSERT(m_value.object->find(key) != m_value.object->end()); - return m_value.object->find(key)->second; - } - - JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()))); - } - - /*! - @brief access specified object element with default value - - Returns either a copy of an object's element at the specified key @a key - or a given default value if no element with key @a key exists. - - The function is basically equivalent to executing - @code {.cpp} - try { - return at(key); - } catch(out_of_range) { - return default_value; - } - @endcode - - @note Unlike @ref at(const typename object_t::key_type&), this function - does not throw if the given key @a key was not found. - - @note Unlike @ref operator[](const typename object_t::key_type& key), this - function does not implicitly add an element to the position defined by @a - key. This function is furthermore also applicable to const objects. - - @param[in] key key of the element to access - @param[in] default_value the value to return if @a key is not found - - @tparam ValueType type compatible to JSON values, for instance `int` for - JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for - JSON arrays. Note the type of the expected value at @a key and the default - value @a default_value must be compatible. - - @return copy of the element at key @a key or @a default_value if @a key - is not found - - @throw type_error.302 if @a default_value does not match the type of the - value at @a key - @throw type_error.306 if the JSON value is not an object; in that case, - using `value()` with a key makes no sense. - - @complexity Logarithmic in the size of the container. - - @liveexample{The example below shows how object elements can be queried - with a default value.,basic_json__value} - - @sa @ref at(const typename object_t::key_type&) for access by reference - with range checking - @sa @ref operator[](const typename object_t::key_type&) for unchecked - access by reference - - @since version 1.0.0 - */ - // using std::is_convertible in a std::enable_if will fail when using explicit conversions - template < class ValueType, typename std::enable_if < - detail::is_getable::value - && !std::is_same::value, int >::type = 0 > - ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const - { - // at only works for objects - if (JSON_HEDLEY_LIKELY(is_object())) - { - // if key is found, return value and given default value otherwise - const auto it = find(key); - if (it != end()) - { - return it->template get(); - } - - return default_value; - } - - JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()))); - } - - /*! - @brief overload for a default value of type const char* - @copydoc basic_json::value(const typename object_t::key_type&, const ValueType&) const - */ - string_t value(const typename object_t::key_type& key, const char* default_value) const - { - return value(key, string_t(default_value)); - } - - /*! - @brief access specified object element via JSON Pointer with default value - - Returns either a copy of an object's element at the specified key @a key - or a given default value if no element with key @a key exists. - - The function is basically equivalent to executing - @code {.cpp} - try { - return at(ptr); - } catch(out_of_range) { - return default_value; - } - @endcode - - @note Unlike @ref at(const json_pointer&), this function does not throw - if the given key @a key was not found. - - @param[in] ptr a JSON pointer to the element to access - @param[in] default_value the value to return if @a ptr found no value - - @tparam ValueType type compatible to JSON values, for instance `int` for - JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for - JSON arrays. Note the type of the expected value at @a key and the default - value @a default_value must be compatible. - - @return copy of the element at key @a key or @a default_value if @a key - is not found - - @throw type_error.302 if @a default_value does not match the type of the - value at @a ptr - @throw type_error.306 if the JSON value is not an object; in that case, - using `value()` with a key makes no sense. - - @complexity Logarithmic in the size of the container. - - @liveexample{The example below shows how object elements can be queried - with a default value.,basic_json__value_ptr} - - @sa @ref operator[](const json_pointer&) for unchecked access by reference - - @since version 2.0.2 - */ - template::value, int>::type = 0> - ValueType value(const json_pointer& ptr, const ValueType& default_value) const - { - // at only works for objects - if (JSON_HEDLEY_LIKELY(is_object())) - { - // if pointer resolves a value, return it or use default value - JSON_TRY - { - return ptr.get_checked(this).template get(); - } - JSON_INTERNAL_CATCH (out_of_range&) - { - return default_value; - } - } - - JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()))); - } - - /*! - @brief overload for a default value of type const char* - @copydoc basic_json::value(const json_pointer&, ValueType) const - */ - JSON_HEDLEY_NON_NULL(3) - string_t value(const json_pointer& ptr, const char* default_value) const - { - return value(ptr, string_t(default_value)); - } - - /*! - @brief access the first element - - Returns a reference to the first element in the container. For a JSON - container `c`, the expression `c.front()` is equivalent to `*c.begin()`. - - @return In case of a structured type (array or object), a reference to the - first element is returned. In case of number, string, boolean, or binary - values, a reference to the value is returned. - - @complexity Constant. - - @pre The JSON value must not be `null` (would throw `std::out_of_range`) - or an empty array or object (undefined behavior, **guarded by - assertions**). - @post The JSON value remains unchanged. - - @throw invalid_iterator.214 when called on `null` value - - @liveexample{The following code shows an example for `front()`.,front} - - @sa @ref back() -- access the last element - - @since version 1.0.0 - */ - reference front() - { - return *begin(); - } - - /*! - @copydoc basic_json::front() - */ - const_reference front() const - { - return *cbegin(); - } - - /*! - @brief access the last element - - Returns a reference to the last element in the container. For a JSON - container `c`, the expression `c.back()` is equivalent to - @code {.cpp} - auto tmp = c.end(); - --tmp; - return *tmp; - @endcode - - @return In case of a structured type (array or object), a reference to the - last element is returned. In case of number, string, boolean, or binary - values, a reference to the value is returned. - - @complexity Constant. - - @pre The JSON value must not be `null` (would throw `std::out_of_range`) - or an empty array or object (undefined behavior, **guarded by - assertions**). - @post The JSON value remains unchanged. - - @throw invalid_iterator.214 when called on a `null` value. See example - below. - - @liveexample{The following code shows an example for `back()`.,back} - - @sa @ref front() -- access the first element - - @since version 1.0.0 - */ - reference back() - { - auto tmp = end(); - --tmp; - return *tmp; - } - - /*! - @copydoc basic_json::back() - */ - const_reference back() const - { - auto tmp = cend(); - --tmp; - return *tmp; - } - - /*! - @brief remove element given an iterator - - Removes the element specified by iterator @a pos. The iterator @a pos must - be valid and dereferenceable. Thus the `end()` iterator (which is valid, - but is not dereferenceable) cannot be used as a value for @a pos. - - If called on a primitive type other than `null`, the resulting JSON value - will be `null`. - - @param[in] pos iterator to the element to remove - @return Iterator following the last removed element. If the iterator @a - pos refers to the last element, the `end()` iterator is returned. - - @tparam IteratorType an @ref iterator or @ref const_iterator - - @post Invalidates iterators and references at or after the point of the - erase, including the `end()` iterator. - - @throw type_error.307 if called on a `null` value; example: `"cannot use - erase() with null"` - @throw invalid_iterator.202 if called on an iterator which does not belong - to the current JSON value; example: `"iterator does not fit current - value"` - @throw invalid_iterator.205 if called on a primitive type with invalid - iterator (i.e., any iterator which is not `begin()`); example: `"iterator - out of range"` - - @complexity The complexity depends on the type: - - objects: amortized constant - - arrays: linear in distance between @a pos and the end of the container - - strings and binary: linear in the length of the member - - other types: constant - - @liveexample{The example shows the result of `erase()` for different JSON - types.,erase__IteratorType} - - @sa @ref erase(IteratorType, IteratorType) -- removes the elements in - the given range - @sa @ref erase(const typename object_t::key_type&) -- removes the element - from an object at the given key - @sa @ref erase(const size_type) -- removes the element from an array at - the given index - - @since version 1.0.0 - */ - template < class IteratorType, typename std::enable_if < - std::is_same::value || - std::is_same::value, int >::type - = 0 > - IteratorType erase(IteratorType pos) - { - // make sure iterator fits the current value - if (JSON_HEDLEY_UNLIKELY(this != pos.m_object)) - { - JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value")); - } - - IteratorType result = end(); - - switch (m_type) - { - case value_t::boolean: - case value_t::number_float: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::string: - case value_t::binary: - { - if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin())) - { - JSON_THROW(invalid_iterator::create(205, "iterator out of range")); - } - - if (is_string()) - { - AllocatorType alloc; - std::allocator_traits::destroy(alloc, m_value.string); - std::allocator_traits::deallocate(alloc, m_value.string, 1); - m_value.string = nullptr; - } - else if (is_binary()) - { - AllocatorType alloc; - std::allocator_traits::destroy(alloc, m_value.binary); - std::allocator_traits::deallocate(alloc, m_value.binary, 1); - m_value.binary = nullptr; - } - - m_type = value_t::null; - assert_invariant(); - break; - } - - case value_t::object: - { - result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator); - break; - } - - case value_t::array: - { - result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator); - break; - } - - default: - JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()))); - } - - return result; - } - - /*! - @brief remove elements given an iterator range - - Removes the element specified by the range `[first; last)`. The iterator - @a first does not need to be dereferenceable if `first == last`: erasing - an empty range is a no-op. - - If called on a primitive type other than `null`, the resulting JSON value - will be `null`. - - @param[in] first iterator to the beginning of the range to remove - @param[in] last iterator past the end of the range to remove - @return Iterator following the last removed element. If the iterator @a - second refers to the last element, the `end()` iterator is returned. - - @tparam IteratorType an @ref iterator or @ref const_iterator - - @post Invalidates iterators and references at or after the point of the - erase, including the `end()` iterator. - - @throw type_error.307 if called on a `null` value; example: `"cannot use - erase() with null"` - @throw invalid_iterator.203 if called on iterators which does not belong - to the current JSON value; example: `"iterators do not fit current value"` - @throw invalid_iterator.204 if called on a primitive type with invalid - iterators (i.e., if `first != begin()` and `last != end()`); example: - `"iterators out of range"` - - @complexity The complexity depends on the type: - - objects: `log(size()) + std::distance(first, last)` - - arrays: linear in the distance between @a first and @a last, plus linear - in the distance between @a last and end of the container - - strings and binary: linear in the length of the member - - other types: constant - - @liveexample{The example shows the result of `erase()` for different JSON - types.,erase__IteratorType_IteratorType} - - @sa @ref erase(IteratorType) -- removes the element at a given position - @sa @ref erase(const typename object_t::key_type&) -- removes the element - from an object at the given key - @sa @ref erase(const size_type) -- removes the element from an array at - the given index - - @since version 1.0.0 - */ - template < class IteratorType, typename std::enable_if < - std::is_same::value || - std::is_same::value, int >::type - = 0 > - IteratorType erase(IteratorType first, IteratorType last) - { - // make sure iterator fits the current value - if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object)) - { - JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value")); - } - - IteratorType result = end(); - - switch (m_type) - { - case value_t::boolean: - case value_t::number_float: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::string: - case value_t::binary: - { - if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin() - || !last.m_it.primitive_iterator.is_end())) - { - JSON_THROW(invalid_iterator::create(204, "iterators out of range")); - } - - if (is_string()) - { - AllocatorType alloc; - std::allocator_traits::destroy(alloc, m_value.string); - std::allocator_traits::deallocate(alloc, m_value.string, 1); - m_value.string = nullptr; - } - else if (is_binary()) - { - AllocatorType alloc; - std::allocator_traits::destroy(alloc, m_value.binary); - std::allocator_traits::deallocate(alloc, m_value.binary, 1); - m_value.binary = nullptr; - } - - m_type = value_t::null; - assert_invariant(); - break; - } - - case value_t::object: - { - result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator, - last.m_it.object_iterator); - break; - } - - case value_t::array: - { - result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator, - last.m_it.array_iterator); - break; - } - - default: - JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()))); - } - - return result; - } - - /*! - @brief remove element from a JSON object given a key - - Removes elements from a JSON object with the key value @a key. - - @param[in] key value of the elements to remove - - @return Number of elements removed. If @a ObjectType is the default - `std::map` type, the return value will always be `0` (@a key was not - found) or `1` (@a key was found). - - @post References and iterators to the erased elements are invalidated. - Other references and iterators are not affected. - - @throw type_error.307 when called on a type other than JSON object; - example: `"cannot use erase() with null"` - - @complexity `log(size()) + count(key)` - - @liveexample{The example shows the effect of `erase()`.,erase__key_type} - - @sa @ref erase(IteratorType) -- removes the element at a given position - @sa @ref erase(IteratorType, IteratorType) -- removes the elements in - the given range - @sa @ref erase(const size_type) -- removes the element from an array at - the given index - - @since version 1.0.0 - */ - size_type erase(const typename object_t::key_type& key) - { - // this erase only works for objects - if (JSON_HEDLEY_LIKELY(is_object())) - { - return m_value.object->erase(key); - } - - JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()))); - } - - /*! - @brief remove element from a JSON array given an index - - Removes element from a JSON array at the index @a idx. - - @param[in] idx index of the element to remove - - @throw type_error.307 when called on a type other than JSON object; - example: `"cannot use erase() with null"` - @throw out_of_range.401 when `idx >= size()`; example: `"array index 17 - is out of range"` - - @complexity Linear in distance between @a idx and the end of the container. - - @liveexample{The example shows the effect of `erase()`.,erase__size_type} - - @sa @ref erase(IteratorType) -- removes the element at a given position - @sa @ref erase(IteratorType, IteratorType) -- removes the elements in - the given range - @sa @ref erase(const typename object_t::key_type&) -- removes the element - from an object at the given key - - @since version 1.0.0 - */ - void erase(const size_type idx) - { - // this erase only works for arrays - if (JSON_HEDLEY_LIKELY(is_array())) - { - if (JSON_HEDLEY_UNLIKELY(idx >= size())) - { - JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range")); - } - - m_value.array->erase(m_value.array->begin() + static_cast(idx)); - } - else - { - JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()))); - } - } - - /// @} - - - //////////// - // lookup // - //////////// - - /// @name lookup - /// @{ - - /*! - @brief find an element in a JSON object - - Finds an element in a JSON object with key equivalent to @a key. If the - element is not found or the JSON value is not an object, end() is - returned. - - @note This method always returns @ref end() when executed on a JSON type - that is not an object. - - @param[in] key key value of the element to search for. - - @return Iterator to an element with key equivalent to @a key. If no such - element is found or the JSON value is not an object, past-the-end (see - @ref end()) iterator is returned. - - @complexity Logarithmic in the size of the JSON object. - - @liveexample{The example shows how `find()` is used.,find__key_type} - - @sa @ref contains(KeyT&&) const -- checks whether a key exists - - @since version 1.0.0 - */ - template - iterator find(KeyT&& key) - { - auto result = end(); - - if (is_object()) - { - result.m_it.object_iterator = m_value.object->find(std::forward(key)); - } - - return result; - } - - /*! - @brief find an element in a JSON object - @copydoc find(KeyT&&) - */ - template - const_iterator find(KeyT&& key) const - { - auto result = cend(); - - if (is_object()) - { - result.m_it.object_iterator = m_value.object->find(std::forward(key)); - } - - return result; - } - - /*! - @brief returns the number of occurrences of a key in a JSON object - - Returns the number of elements with key @a key. If ObjectType is the - default `std::map` type, the return value will always be `0` (@a key was - not found) or `1` (@a key was found). - - @note This method always returns `0` when executed on a JSON type that is - not an object. - - @param[in] key key value of the element to count - - @return Number of elements with key @a key. If the JSON value is not an - object, the return value will be `0`. - - @complexity Logarithmic in the size of the JSON object. - - @liveexample{The example shows how `count()` is used.,count} - - @since version 1.0.0 - */ - template - size_type count(KeyT&& key) const - { - // return 0 for all nonobject types - return is_object() ? m_value.object->count(std::forward(key)) : 0; - } - - /*! - @brief check the existence of an element in a JSON object - - Check whether an element exists in a JSON object with key equivalent to - @a key. If the element is not found or the JSON value is not an object, - false is returned. - - @note This method always returns false when executed on a JSON type - that is not an object. - - @param[in] key key value to check its existence. - - @return true if an element with specified @a key exists. If no such - element with such key is found or the JSON value is not an object, - false is returned. - - @complexity Logarithmic in the size of the JSON object. - - @liveexample{The following code shows an example for `contains()`.,contains} - - @sa @ref find(KeyT&&) -- returns an iterator to an object element - @sa @ref contains(const json_pointer&) const -- checks the existence for a JSON pointer - - @since version 3.6.0 - */ - template < typename KeyT, typename std::enable_if < - !std::is_same::type, json_pointer>::value, int >::type = 0 > - bool contains(KeyT && key) const - { - return is_object() && m_value.object->find(std::forward(key)) != m_value.object->end(); - } - - /*! - @brief check the existence of an element in a JSON object given a JSON pointer - - Check whether the given JSON pointer @a ptr can be resolved in the current - JSON value. - - @note This method can be executed on any JSON value type. - - @param[in] ptr JSON pointer to check its existence. - - @return true if the JSON pointer can be resolved to a stored value, false - otherwise. - - @post If `j.contains(ptr)` returns true, it is safe to call `j[ptr]`. - - @throw parse_error.106 if an array index begins with '0' - @throw parse_error.109 if an array index was not a number - - @complexity Logarithmic in the size of the JSON object. - - @liveexample{The following code shows an example for `contains()`.,contains_json_pointer} - - @sa @ref contains(KeyT &&) const -- checks the existence of a key - - @since version 3.7.0 - */ - bool contains(const json_pointer& ptr) const - { - return ptr.contains(this); - } - - /// @} - - - /////////////// - // iterators // - /////////////// - - /// @name iterators - /// @{ - - /*! - @brief returns an iterator to the first element - - Returns an iterator to the first element. - - @image html range-begin-end.svg "Illustration from cppreference.com" - - @return iterator to the first element - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is constant. - - @liveexample{The following code shows an example for `begin()`.,begin} - - @sa @ref cbegin() -- returns a const iterator to the beginning - @sa @ref end() -- returns an iterator to the end - @sa @ref cend() -- returns a const iterator to the end - - @since version 1.0.0 - */ - iterator begin() noexcept - { - iterator result(this); - result.set_begin(); - return result; - } - - /*! - @copydoc basic_json::cbegin() - */ - const_iterator begin() const noexcept - { - return cbegin(); - } - - /*! - @brief returns a const iterator to the first element - - Returns a const iterator to the first element. - - @image html range-begin-end.svg "Illustration from cppreference.com" - - @return const iterator to the first element - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is constant. - - Has the semantics of `const_cast(*this).begin()`. - - @liveexample{The following code shows an example for `cbegin()`.,cbegin} - - @sa @ref begin() -- returns an iterator to the beginning - @sa @ref end() -- returns an iterator to the end - @sa @ref cend() -- returns a const iterator to the end - - @since version 1.0.0 - */ - const_iterator cbegin() const noexcept - { - const_iterator result(this); - result.set_begin(); - return result; - } - - /*! - @brief returns an iterator to one past the last element - - Returns an iterator to one past the last element. - - @image html range-begin-end.svg "Illustration from cppreference.com" - - @return iterator one past the last element - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is constant. - - @liveexample{The following code shows an example for `end()`.,end} - - @sa @ref cend() -- returns a const iterator to the end - @sa @ref begin() -- returns an iterator to the beginning - @sa @ref cbegin() -- returns a const iterator to the beginning - - @since version 1.0.0 - */ - iterator end() noexcept - { - iterator result(this); - result.set_end(); - return result; - } - - /*! - @copydoc basic_json::cend() - */ - const_iterator end() const noexcept - { - return cend(); - } - - /*! - @brief returns a const iterator to one past the last element - - Returns a const iterator to one past the last element. - - @image html range-begin-end.svg "Illustration from cppreference.com" - - @return const iterator one past the last element - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is constant. - - Has the semantics of `const_cast(*this).end()`. - - @liveexample{The following code shows an example for `cend()`.,cend} - - @sa @ref end() -- returns an iterator to the end - @sa @ref begin() -- returns an iterator to the beginning - @sa @ref cbegin() -- returns a const iterator to the beginning - - @since version 1.0.0 - */ - const_iterator cend() const noexcept - { - const_iterator result(this); - result.set_end(); - return result; - } - - /*! - @brief returns an iterator to the reverse-beginning - - Returns an iterator to the reverse-beginning; that is, the last element. - - @image html range-rbegin-rend.svg "Illustration from cppreference.com" - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer) - requirements: - - The complexity is constant. - - Has the semantics of `reverse_iterator(end())`. - - @liveexample{The following code shows an example for `rbegin()`.,rbegin} - - @sa @ref crbegin() -- returns a const reverse iterator to the beginning - @sa @ref rend() -- returns a reverse iterator to the end - @sa @ref crend() -- returns a const reverse iterator to the end - - @since version 1.0.0 - */ - reverse_iterator rbegin() noexcept - { - return reverse_iterator(end()); - } - - /*! - @copydoc basic_json::crbegin() - */ - const_reverse_iterator rbegin() const noexcept - { - return crbegin(); - } - - /*! - @brief returns an iterator to the reverse-end - - Returns an iterator to the reverse-end; that is, one before the first - element. - - @image html range-rbegin-rend.svg "Illustration from cppreference.com" - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer) - requirements: - - The complexity is constant. - - Has the semantics of `reverse_iterator(begin())`. - - @liveexample{The following code shows an example for `rend()`.,rend} - - @sa @ref crend() -- returns a const reverse iterator to the end - @sa @ref rbegin() -- returns a reverse iterator to the beginning - @sa @ref crbegin() -- returns a const reverse iterator to the beginning - - @since version 1.0.0 - */ - reverse_iterator rend() noexcept - { - return reverse_iterator(begin()); - } - - /*! - @copydoc basic_json::crend() - */ - const_reverse_iterator rend() const noexcept - { - return crend(); - } - - /*! - @brief returns a const reverse iterator to the last element - - Returns a const iterator to the reverse-beginning; that is, the last - element. - - @image html range-rbegin-rend.svg "Illustration from cppreference.com" - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer) - requirements: - - The complexity is constant. - - Has the semantics of `const_cast(*this).rbegin()`. - - @liveexample{The following code shows an example for `crbegin()`.,crbegin} - - @sa @ref rbegin() -- returns a reverse iterator to the beginning - @sa @ref rend() -- returns a reverse iterator to the end - @sa @ref crend() -- returns a const reverse iterator to the end - - @since version 1.0.0 - */ - const_reverse_iterator crbegin() const noexcept - { - return const_reverse_iterator(cend()); - } - - /*! - @brief returns a const reverse iterator to one before the first - - Returns a const reverse iterator to the reverse-end; that is, one before - the first element. - - @image html range-rbegin-rend.svg "Illustration from cppreference.com" - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer) - requirements: - - The complexity is constant. - - Has the semantics of `const_cast(*this).rend()`. - - @liveexample{The following code shows an example for `crend()`.,crend} - - @sa @ref rend() -- returns a reverse iterator to the end - @sa @ref rbegin() -- returns a reverse iterator to the beginning - @sa @ref crbegin() -- returns a const reverse iterator to the beginning - - @since version 1.0.0 - */ - const_reverse_iterator crend() const noexcept - { - return const_reverse_iterator(cbegin()); - } - - public: - /*! - @brief wrapper to access iterator member functions in range-based for - - This function allows to access @ref iterator::key() and @ref - iterator::value() during range-based for loops. In these loops, a - reference to the JSON values is returned, so there is no access to the - underlying iterator. - - For loop without iterator_wrapper: - - @code{cpp} - for (auto it = j_object.begin(); it != j_object.end(); ++it) - { - std::cout << "key: " << it.key() << ", value:" << it.value() << '\n'; - } - @endcode - - Range-based for loop without iterator proxy: - - @code{cpp} - for (auto it : j_object) - { - // "it" is of type json::reference and has no key() member - std::cout << "value: " << it << '\n'; - } - @endcode - - Range-based for loop with iterator proxy: - - @code{cpp} - for (auto it : json::iterator_wrapper(j_object)) - { - std::cout << "key: " << it.key() << ", value:" << it.value() << '\n'; - } - @endcode - - @note When iterating over an array, `key()` will return the index of the - element as string (see example). - - @param[in] ref reference to a JSON value - @return iteration proxy object wrapping @a ref with an interface to use in - range-based for loops - - @liveexample{The following code shows how the wrapper is used,iterator_wrapper} - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Constant. - - @note The name of this function is not yet final and may change in the - future. - - @deprecated This stream operator is deprecated and will be removed in - future 4.0.0 of the library. Please use @ref items() instead; - that is, replace `json::iterator_wrapper(j)` with `j.items()`. - */ - JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items()) - static iteration_proxy iterator_wrapper(reference ref) noexcept - { - return ref.items(); - } - - /*! - @copydoc iterator_wrapper(reference) - */ - JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items()) - static iteration_proxy iterator_wrapper(const_reference ref) noexcept - { - return ref.items(); - } - - /*! - @brief helper to access iterator member functions in range-based for - - This function allows to access @ref iterator::key() and @ref - iterator::value() during range-based for loops. In these loops, a - reference to the JSON values is returned, so there is no access to the - underlying iterator. - - For loop without `items()` function: - - @code{cpp} - for (auto it = j_object.begin(); it != j_object.end(); ++it) - { - std::cout << "key: " << it.key() << ", value:" << it.value() << '\n'; - } - @endcode - - Range-based for loop without `items()` function: - - @code{cpp} - for (auto it : j_object) - { - // "it" is of type json::reference and has no key() member - std::cout << "value: " << it << '\n'; - } - @endcode - - Range-based for loop with `items()` function: - - @code{cpp} - for (auto& el : j_object.items()) - { - std::cout << "key: " << el.key() << ", value:" << el.value() << '\n'; - } - @endcode - - The `items()` function also allows to use - [structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding) - (C++17): - - @code{cpp} - for (auto& [key, val] : j_object.items()) - { - std::cout << "key: " << key << ", value:" << val << '\n'; - } - @endcode - - @note When iterating over an array, `key()` will return the index of the - element as string (see example). For primitive types (e.g., numbers), - `key()` returns an empty string. - - @warning Using `items()` on temporary objects is dangerous. Make sure the - object's lifetime exeeds the iteration. See - for more - information. - - @return iteration proxy object wrapping @a ref with an interface to use in - range-based for loops - - @liveexample{The following code shows how the function is used.,items} - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Constant. - - @since version 3.1.0, structured bindings support since 3.5.0. - */ - iteration_proxy items() noexcept - { - return iteration_proxy(*this); - } - - /*! - @copydoc items() - */ - iteration_proxy items() const noexcept - { - return iteration_proxy(*this); - } - - /// @} - - - ////////////// - // capacity // - ////////////// - - /// @name capacity - /// @{ - - /*! - @brief checks whether the container is empty. - - Checks if a JSON value has no elements (i.e. whether its @ref size is `0`). - - @return The return value depends on the different types and is - defined as follows: - Value type | return value - ----------- | ------------- - null | `true` - boolean | `false` - string | `false` - number | `false` - binary | `false` - object | result of function `object_t::empty()` - array | result of function `array_t::empty()` - - @liveexample{The following code uses `empty()` to check if a JSON - object contains any elements.,empty} - - @complexity Constant, as long as @ref array_t and @ref object_t satisfy - the Container concept; that is, their `empty()` functions have constant - complexity. - - @iterators No changes. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @note This function does not return whether a string stored as JSON value - is empty - it returns whether the JSON container itself is empty which is - false in the case of a string. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is constant. - - Has the semantics of `begin() == end()`. - - @sa @ref size() -- returns the number of elements - - @since version 1.0.0 - */ - bool empty() const noexcept - { - switch (m_type) - { - case value_t::null: - { - // null values are empty - return true; - } - - case value_t::array: - { - // delegate call to array_t::empty() - return m_value.array->empty(); - } - - case value_t::object: - { - // delegate call to object_t::empty() - return m_value.object->empty(); - } - - default: - { - // all other types are nonempty - return false; - } - } - } - - /*! - @brief returns the number of elements - - Returns the number of elements in a JSON value. - - @return The return value depends on the different types and is - defined as follows: - Value type | return value - ----------- | ------------- - null | `0` - boolean | `1` - string | `1` - number | `1` - binary | `1` - object | result of function object_t::size() - array | result of function array_t::size() - - @liveexample{The following code calls `size()` on the different value - types.,size} - - @complexity Constant, as long as @ref array_t and @ref object_t satisfy - the Container concept; that is, their size() functions have constant - complexity. - - @iterators No changes. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @note This function does not return the length of a string stored as JSON - value - it returns the number of elements in the JSON value which is 1 in - the case of a string. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is constant. - - Has the semantics of `std::distance(begin(), end())`. - - @sa @ref empty() -- checks whether the container is empty - @sa @ref max_size() -- returns the maximal number of elements - - @since version 1.0.0 - */ - size_type size() const noexcept - { - switch (m_type) - { - case value_t::null: - { - // null values are empty - return 0; - } - - case value_t::array: - { - // delegate call to array_t::size() - return m_value.array->size(); - } - - case value_t::object: - { - // delegate call to object_t::size() - return m_value.object->size(); - } - - default: - { - // all other types have size 1 - return 1; - } - } - } - - /*! - @brief returns the maximum possible number of elements - - Returns the maximum number of elements a JSON value is able to hold due to - system or library implementation limitations, i.e. `std::distance(begin(), - end())` for the JSON value. - - @return The return value depends on the different types and is - defined as follows: - Value type | return value - ----------- | ------------- - null | `0` (same as `size()`) - boolean | `1` (same as `size()`) - string | `1` (same as `size()`) - number | `1` (same as `size()`) - binary | `1` (same as `size()`) - object | result of function `object_t::max_size()` - array | result of function `array_t::max_size()` - - @liveexample{The following code calls `max_size()` on the different value - types. Note the output is implementation specific.,max_size} - - @complexity Constant, as long as @ref array_t and @ref object_t satisfy - the Container concept; that is, their `max_size()` functions have constant - complexity. - - @iterators No changes. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is constant. - - Has the semantics of returning `b.size()` where `b` is the largest - possible JSON value. - - @sa @ref size() -- returns the number of elements - - @since version 1.0.0 - */ - size_type max_size() const noexcept - { - switch (m_type) - { - case value_t::array: - { - // delegate call to array_t::max_size() - return m_value.array->max_size(); - } - - case value_t::object: - { - // delegate call to object_t::max_size() - return m_value.object->max_size(); - } - - default: - { - // all other types have max_size() == size() - return size(); - } - } - } - - /// @} - - - /////////////// - // modifiers // - /////////////// - - /// @name modifiers - /// @{ - - /*! - @brief clears the contents - - Clears the content of a JSON value and resets it to the default value as - if @ref basic_json(value_t) would have been called with the current value - type from @ref type(): - - Value type | initial value - ----------- | ------------- - null | `null` - boolean | `false` - string | `""` - number | `0` - binary | An empty byte vector - object | `{}` - array | `[]` - - @post Has the same effect as calling - @code {.cpp} - *this = basic_json(type()); - @endcode - - @liveexample{The example below shows the effect of `clear()` to different - JSON types.,clear} - - @complexity Linear in the size of the JSON value. - - @iterators All iterators, pointers and references related to this container - are invalidated. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @sa @ref basic_json(value_t) -- constructor that creates an object with the - same value than calling `clear()` - - @since version 1.0.0 - */ - void clear() noexcept - { - switch (m_type) - { - case value_t::number_integer: - { - m_value.number_integer = 0; - break; - } - - case value_t::number_unsigned: - { - m_value.number_unsigned = 0; - break; - } - - case value_t::number_float: - { - m_value.number_float = 0.0; - break; - } - - case value_t::boolean: - { - m_value.boolean = false; - break; - } - - case value_t::string: - { - m_value.string->clear(); - break; - } - - case value_t::binary: - { - m_value.binary->clear(); - break; - } - - case value_t::array: - { - m_value.array->clear(); - break; - } - - case value_t::object: - { - m_value.object->clear(); - break; - } - - default: - break; - } - } - - /*! - @brief add an object to an array - - Appends the given element @a val to the end of the JSON value. If the - function is called on a JSON null value, an empty array is created before - appending @a val. - - @param[in] val the value to add to the JSON array - - @throw type_error.308 when called on a type other than JSON array or - null; example: `"cannot use push_back() with number"` - - @complexity Amortized constant. - - @liveexample{The example shows how `push_back()` and `+=` can be used to - add elements to a JSON array. Note how the `null` value was silently - converted to a JSON array.,push_back} - - @since version 1.0.0 - */ - void push_back(basic_json&& val) - { - // push_back only works for null objects or arrays - if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array()))) - { - JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()))); - } - - // transform null object into an array - if (is_null()) - { - m_type = value_t::array; - m_value = value_t::array; - assert_invariant(); - } - - // add element to array (move semantics) - m_value.array->push_back(std::move(val)); - // if val is moved from, basic_json move constructor marks it null so we do not call the destructor - } - - /*! - @brief add an object to an array - @copydoc push_back(basic_json&&) - */ - reference operator+=(basic_json&& val) - { - push_back(std::move(val)); - return *this; - } - - /*! - @brief add an object to an array - @copydoc push_back(basic_json&&) - */ - void push_back(const basic_json& val) - { - // push_back only works for null objects or arrays - if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array()))) - { - JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()))); - } - - // transform null object into an array - if (is_null()) - { - m_type = value_t::array; - m_value = value_t::array; - assert_invariant(); - } - - // add element to array - m_value.array->push_back(val); - } - - /*! - @brief add an object to an array - @copydoc push_back(basic_json&&) - */ - reference operator+=(const basic_json& val) - { - push_back(val); - return *this; - } - - /*! - @brief add an object to an object - - Inserts the given element @a val to the JSON object. If the function is - called on a JSON null value, an empty object is created before inserting - @a val. - - @param[in] val the value to add to the JSON object - - @throw type_error.308 when called on a type other than JSON object or - null; example: `"cannot use push_back() with number"` - - @complexity Logarithmic in the size of the container, O(log(`size()`)). - - @liveexample{The example shows how `push_back()` and `+=` can be used to - add elements to a JSON object. Note how the `null` value was silently - converted to a JSON object.,push_back__object_t__value} - - @since version 1.0.0 - */ - void push_back(const typename object_t::value_type& val) - { - // push_back only works for null objects or objects - if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object()))) - { - JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()))); - } - - // transform null object into an object - if (is_null()) - { - m_type = value_t::object; - m_value = value_t::object; - assert_invariant(); - } - - // add element to array - m_value.object->insert(val); - } - - /*! - @brief add an object to an object - @copydoc push_back(const typename object_t::value_type&) - */ - reference operator+=(const typename object_t::value_type& val) - { - push_back(val); - return *this; - } - - /*! - @brief add an object to an object - - This function allows to use `push_back` with an initializer list. In case - - 1. the current value is an object, - 2. the initializer list @a init contains only two elements, and - 3. the first element of @a init is a string, - - @a init is converted into an object element and added using - @ref push_back(const typename object_t::value_type&). Otherwise, @a init - is converted to a JSON value and added using @ref push_back(basic_json&&). - - @param[in] init an initializer list - - @complexity Linear in the size of the initializer list @a init. - - @note This function is required to resolve an ambiguous overload error, - because pairs like `{"key", "value"}` can be both interpreted as - `object_t::value_type` or `std::initializer_list`, see - https://github.com/nlohmann/json/issues/235 for more information. - - @liveexample{The example shows how initializer lists are treated as - objects when possible.,push_back__initializer_list} - */ - void push_back(initializer_list_t init) - { - if (is_object() && init.size() == 2 && (*init.begin())->is_string()) - { - basic_json&& key = init.begin()->moved_or_copied(); - push_back(typename object_t::value_type( - std::move(key.get_ref()), (init.begin() + 1)->moved_or_copied())); - } - else - { - push_back(basic_json(init)); - } - } - - /*! - @brief add an object to an object - @copydoc push_back(initializer_list_t) - */ - reference operator+=(initializer_list_t init) - { - push_back(init); - return *this; - } - - /*! - @brief add an object to an array - - Creates a JSON value from the passed parameters @a args to the end of the - JSON value. If the function is called on a JSON null value, an empty array - is created before appending the value created from @a args. - - @param[in] args arguments to forward to a constructor of @ref basic_json - @tparam Args compatible types to create a @ref basic_json object - - @return reference to the inserted element - - @throw type_error.311 when called on a type other than JSON array or - null; example: `"cannot use emplace_back() with number"` - - @complexity Amortized constant. - - @liveexample{The example shows how `push_back()` can be used to add - elements to a JSON array. Note how the `null` value was silently converted - to a JSON array.,emplace_back} - - @since version 2.0.8, returns reference since 3.7.0 - */ - template - reference emplace_back(Args&& ... args) - { - // emplace_back only works for null objects or arrays - if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array()))) - { - JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name()))); - } - - // transform null object into an array - if (is_null()) - { - m_type = value_t::array; - m_value = value_t::array; - assert_invariant(); - } - - // add element to array (perfect forwarding) -#ifdef JSON_HAS_CPP_17 - return m_value.array->emplace_back(std::forward(args)...); -#else - m_value.array->emplace_back(std::forward(args)...); - return m_value.array->back(); -#endif - } - - /*! - @brief add an object to an object if key does not exist - - Inserts a new element into a JSON object constructed in-place with the - given @a args if there is no element with the key in the container. If the - function is called on a JSON null value, an empty object is created before - appending the value created from @a args. - - @param[in] args arguments to forward to a constructor of @ref basic_json - @tparam Args compatible types to create a @ref basic_json object - - @return a pair consisting of an iterator to the inserted element, or the - already-existing element if no insertion happened, and a bool - denoting whether the insertion took place. - - @throw type_error.311 when called on a type other than JSON object or - null; example: `"cannot use emplace() with number"` - - @complexity Logarithmic in the size of the container, O(log(`size()`)). - - @liveexample{The example shows how `emplace()` can be used to add elements - to a JSON object. Note how the `null` value was silently converted to a - JSON object. Further note how no value is added if there was already one - value stored with the same key.,emplace} - - @since version 2.0.8 - */ - template - std::pair emplace(Args&& ... args) - { - // emplace only works for null objects or arrays - if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object()))) - { - JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name()))); - } - - // transform null object into an object - if (is_null()) - { - m_type = value_t::object; - m_value = value_t::object; - assert_invariant(); - } - - // add element to array (perfect forwarding) - auto res = m_value.object->emplace(std::forward(args)...); - // create result iterator and set iterator to the result of emplace - auto it = begin(); - it.m_it.object_iterator = res.first; - - // return pair of iterator and boolean - return {it, res.second}; - } - - /// Helper for insertion of an iterator - /// @note: This uses std::distance to support GCC 4.8, - /// see https://github.com/nlohmann/json/pull/1257 - template - iterator insert_iterator(const_iterator pos, Args&& ... args) - { - iterator result(this); - JSON_ASSERT(m_value.array != nullptr); - - auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator); - m_value.array->insert(pos.m_it.array_iterator, std::forward(args)...); - result.m_it.array_iterator = m_value.array->begin() + insert_pos; - - // This could have been written as: - // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val); - // but the return value of insert is missing in GCC 4.8, so it is written this way instead. - - return result; - } - - /*! - @brief inserts element - - Inserts element @a val before iterator @a pos. - - @param[in] pos iterator before which the content will be inserted; may be - the end() iterator - @param[in] val element to insert - @return iterator pointing to the inserted @a val. - - @throw type_error.309 if called on JSON values other than arrays; - example: `"cannot use insert() with string"` - @throw invalid_iterator.202 if @a pos is not an iterator of *this; - example: `"iterator does not fit current value"` - - @complexity Constant plus linear in the distance between @a pos and end of - the container. - - @liveexample{The example shows how `insert()` is used.,insert} - - @since version 1.0.0 - */ - iterator insert(const_iterator pos, const basic_json& val) - { - // insert only works for arrays - if (JSON_HEDLEY_LIKELY(is_array())) - { - // check if iterator pos fits to this JSON value - if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) - { - JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value")); - } - - // insert to array and return iterator - return insert_iterator(pos, val); - } - - JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()))); - } - - /*! - @brief inserts element - @copydoc insert(const_iterator, const basic_json&) - */ - iterator insert(const_iterator pos, basic_json&& val) - { - return insert(pos, val); - } - - /*! - @brief inserts elements - - Inserts @a cnt copies of @a val before iterator @a pos. - - @param[in] pos iterator before which the content will be inserted; may be - the end() iterator - @param[in] cnt number of copies of @a val to insert - @param[in] val element to insert - @return iterator pointing to the first element inserted, or @a pos if - `cnt==0` - - @throw type_error.309 if called on JSON values other than arrays; example: - `"cannot use insert() with string"` - @throw invalid_iterator.202 if @a pos is not an iterator of *this; - example: `"iterator does not fit current value"` - - @complexity Linear in @a cnt plus linear in the distance between @a pos - and end of the container. - - @liveexample{The example shows how `insert()` is used.,insert__count} - - @since version 1.0.0 - */ - iterator insert(const_iterator pos, size_type cnt, const basic_json& val) - { - // insert only works for arrays - if (JSON_HEDLEY_LIKELY(is_array())) - { - // check if iterator pos fits to this JSON value - if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) - { - JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value")); - } - - // insert to array and return iterator - return insert_iterator(pos, cnt, val); - } - - JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()))); - } - - /*! - @brief inserts elements - - Inserts elements from range `[first, last)` before iterator @a pos. - - @param[in] pos iterator before which the content will be inserted; may be - the end() iterator - @param[in] first begin of the range of elements to insert - @param[in] last end of the range of elements to insert - - @throw type_error.309 if called on JSON values other than arrays; example: - `"cannot use insert() with string"` - @throw invalid_iterator.202 if @a pos is not an iterator of *this; - example: `"iterator does not fit current value"` - @throw invalid_iterator.210 if @a first and @a last do not belong to the - same JSON value; example: `"iterators do not fit"` - @throw invalid_iterator.211 if @a first or @a last are iterators into - container for which insert is called; example: `"passed iterators may not - belong to container"` - - @return iterator pointing to the first element inserted, or @a pos if - `first==last` - - @complexity Linear in `std::distance(first, last)` plus linear in the - distance between @a pos and end of the container. - - @liveexample{The example shows how `insert()` is used.,insert__range} - - @since version 1.0.0 - */ - iterator insert(const_iterator pos, const_iterator first, const_iterator last) - { - // insert only works for arrays - if (JSON_HEDLEY_UNLIKELY(!is_array())) - { - JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()))); - } - - // check if iterator pos fits to this JSON value - if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) - { - JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value")); - } - - // check if range iterators belong to the same JSON object - if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object)) - { - JSON_THROW(invalid_iterator::create(210, "iterators do not fit")); - } - - if (JSON_HEDLEY_UNLIKELY(first.m_object == this)) - { - JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container")); - } - - // insert to array and return iterator - return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator); - } - - /*! - @brief inserts elements - - Inserts elements from initializer list @a ilist before iterator @a pos. - - @param[in] pos iterator before which the content will be inserted; may be - the end() iterator - @param[in] ilist initializer list to insert the values from - - @throw type_error.309 if called on JSON values other than arrays; example: - `"cannot use insert() with string"` - @throw invalid_iterator.202 if @a pos is not an iterator of *this; - example: `"iterator does not fit current value"` - - @return iterator pointing to the first element inserted, or @a pos if - `ilist` is empty - - @complexity Linear in `ilist.size()` plus linear in the distance between - @a pos and end of the container. - - @liveexample{The example shows how `insert()` is used.,insert__ilist} - - @since version 1.0.0 - */ - iterator insert(const_iterator pos, initializer_list_t ilist) - { - // insert only works for arrays - if (JSON_HEDLEY_UNLIKELY(!is_array())) - { - JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()))); - } - - // check if iterator pos fits to this JSON value - if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) - { - JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value")); - } - - // insert to array and return iterator - return insert_iterator(pos, ilist.begin(), ilist.end()); - } - - /*! - @brief inserts elements - - Inserts elements from range `[first, last)`. - - @param[in] first begin of the range of elements to insert - @param[in] last end of the range of elements to insert - - @throw type_error.309 if called on JSON values other than objects; example: - `"cannot use insert() with string"` - @throw invalid_iterator.202 if iterator @a first or @a last does does not - point to an object; example: `"iterators first and last must point to - objects"` - @throw invalid_iterator.210 if @a first and @a last do not belong to the - same JSON value; example: `"iterators do not fit"` - - @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number - of elements to insert. - - @liveexample{The example shows how `insert()` is used.,insert__range_object} - - @since version 3.0.0 - */ - void insert(const_iterator first, const_iterator last) - { - // insert only works for objects - if (JSON_HEDLEY_UNLIKELY(!is_object())) - { - JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()))); - } - - // check if range iterators belong to the same JSON object - if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object)) - { - JSON_THROW(invalid_iterator::create(210, "iterators do not fit")); - } - - // passed iterators must belong to objects - if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object())) - { - JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects")); - } - - m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator); - } - - /*! - @brief updates a JSON object from another object, overwriting existing keys - - Inserts all values from JSON object @a j and overwrites existing keys. - - @param[in] j JSON object to read values from - - @throw type_error.312 if called on JSON values other than objects; example: - `"cannot use update() with string"` - - @complexity O(N*log(size() + N)), where N is the number of elements to - insert. - - @liveexample{The example shows how `update()` is used.,update} - - @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update - - @since version 3.0.0 - */ - void update(const_reference j) - { - // implicitly convert null value to an empty object - if (is_null()) - { - m_type = value_t::object; - m_value.object = create(); - assert_invariant(); - } - - if (JSON_HEDLEY_UNLIKELY(!is_object())) - { - JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()))); - } - if (JSON_HEDLEY_UNLIKELY(!j.is_object())) - { - JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name()))); - } - - for (auto it = j.cbegin(); it != j.cend(); ++it) - { - m_value.object->operator[](it.key()) = it.value(); - } - } - - /*! - @brief updates a JSON object from another object, overwriting existing keys - - Inserts all values from from range `[first, last)` and overwrites existing - keys. - - @param[in] first begin of the range of elements to insert - @param[in] last end of the range of elements to insert - - @throw type_error.312 if called on JSON values other than objects; example: - `"cannot use update() with string"` - @throw invalid_iterator.202 if iterator @a first or @a last does does not - point to an object; example: `"iterators first and last must point to - objects"` - @throw invalid_iterator.210 if @a first and @a last do not belong to the - same JSON value; example: `"iterators do not fit"` - - @complexity O(N*log(size() + N)), where N is the number of elements to - insert. - - @liveexample{The example shows how `update()` is used__range.,update} - - @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update - - @since version 3.0.0 - */ - void update(const_iterator first, const_iterator last) - { - // implicitly convert null value to an empty object - if (is_null()) - { - m_type = value_t::object; - m_value.object = create(); - assert_invariant(); - } - - if (JSON_HEDLEY_UNLIKELY(!is_object())) - { - JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()))); - } - - // check if range iterators belong to the same JSON object - if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object)) - { - JSON_THROW(invalid_iterator::create(210, "iterators do not fit")); - } - - // passed iterators must belong to objects - if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object() - || !last.m_object->is_object())) - { - JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects")); - } - - for (auto it = first; it != last; ++it) - { - m_value.object->operator[](it.key()) = it.value(); - } - } - - /*! - @brief exchanges the values - - Exchanges the contents of the JSON value with those of @a other. Does not - invoke any move, copy, or swap operations on individual elements. All - iterators and references remain valid. The past-the-end iterator is - invalidated. - - @param[in,out] other JSON value to exchange the contents with - - @complexity Constant. - - @liveexample{The example below shows how JSON values can be swapped with - `swap()`.,swap__reference} - - @since version 1.0.0 - */ - void swap(reference other) noexcept ( - std::is_nothrow_move_constructible::value&& - std::is_nothrow_move_assignable::value&& - std::is_nothrow_move_constructible::value&& - std::is_nothrow_move_assignable::value - ) - { - std::swap(m_type, other.m_type); - std::swap(m_value, other.m_value); - assert_invariant(); - } - - /*! - @brief exchanges the values - - Exchanges the contents of the JSON value from @a left with those of @a right. Does not - invoke any move, copy, or swap operations on individual elements. All - iterators and references remain valid. The past-the-end iterator is - invalidated. implemented as a friend function callable via ADL. - - @param[in,out] left JSON value to exchange the contents with - @param[in,out] right JSON value to exchange the contents with - - @complexity Constant. - - @liveexample{The example below shows how JSON values can be swapped with - `swap()`.,swap__reference} - - @since version 1.0.0 - */ - friend void swap(reference left, reference right) noexcept ( - std::is_nothrow_move_constructible::value&& - std::is_nothrow_move_assignable::value&& - std::is_nothrow_move_constructible::value&& - std::is_nothrow_move_assignable::value - ) - { - left.swap(right); - } - - /*! - @brief exchanges the values - - Exchanges the contents of a JSON array with those of @a other. Does not - invoke any move, copy, or swap operations on individual elements. All - iterators and references remain valid. The past-the-end iterator is - invalidated. - - @param[in,out] other array to exchange the contents with - - @throw type_error.310 when JSON value is not an array; example: `"cannot - use swap() with string"` - - @complexity Constant. - - @liveexample{The example below shows how arrays can be swapped with - `swap()`.,swap__array_t} - - @since version 1.0.0 - */ - void swap(array_t& other) - { - // swap only works for arrays - if (JSON_HEDLEY_LIKELY(is_array())) - { - std::swap(*(m_value.array), other); - } - else - { - JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()))); - } - } - - /*! - @brief exchanges the values - - Exchanges the contents of a JSON object with those of @a other. Does not - invoke any move, copy, or swap operations on individual elements. All - iterators and references remain valid. The past-the-end iterator is - invalidated. - - @param[in,out] other object to exchange the contents with - - @throw type_error.310 when JSON value is not an object; example: - `"cannot use swap() with string"` - - @complexity Constant. - - @liveexample{The example below shows how objects can be swapped with - `swap()`.,swap__object_t} - - @since version 1.0.0 - */ - void swap(object_t& other) - { - // swap only works for objects - if (JSON_HEDLEY_LIKELY(is_object())) - { - std::swap(*(m_value.object), other); - } - else - { - JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()))); - } - } - - /*! - @brief exchanges the values - - Exchanges the contents of a JSON string with those of @a other. Does not - invoke any move, copy, or swap operations on individual elements. All - iterators and references remain valid. The past-the-end iterator is - invalidated. - - @param[in,out] other string to exchange the contents with - - @throw type_error.310 when JSON value is not a string; example: `"cannot - use swap() with boolean"` - - @complexity Constant. - - @liveexample{The example below shows how strings can be swapped with - `swap()`.,swap__string_t} - - @since version 1.0.0 - */ - void swap(string_t& other) - { - // swap only works for strings - if (JSON_HEDLEY_LIKELY(is_string())) - { - std::swap(*(m_value.string), other); - } - else - { - JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()))); - } - } - - /*! - @brief exchanges the values - - Exchanges the contents of a JSON string with those of @a other. Does not - invoke any move, copy, or swap operations on individual elements. All - iterators and references remain valid. The past-the-end iterator is - invalidated. - - @param[in,out] other binary to exchange the contents with - - @throw type_error.310 when JSON value is not a string; example: `"cannot - use swap() with boolean"` - - @complexity Constant. - - @liveexample{The example below shows how strings can be swapped with - `swap()`.,swap__binary_t} - - @since version 3.8.0 - */ - void swap(binary_t& other) - { - // swap only works for strings - if (JSON_HEDLEY_LIKELY(is_binary())) - { - std::swap(*(m_value.binary), other); - } - else - { - JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()))); - } - } - - /// @copydoc swap(binary_t) - void swap(typename binary_t::container_type& other) - { - // swap only works for strings - if (JSON_HEDLEY_LIKELY(is_binary())) - { - std::swap(*(m_value.binary), other); - } - else - { - JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()))); - } - } - - /// @} - - public: - ////////////////////////////////////////// - // lexicographical comparison operators // - ////////////////////////////////////////// - - /// @name lexicographical comparison operators - /// @{ - - /*! - @brief comparison: equal - - Compares two JSON values for equality according to the following rules: - - Two JSON values are equal if (1) they are from the same type and (2) - their stored values are the same according to their respective - `operator==`. - - Integer and floating-point numbers are automatically converted before - comparison. Note that two NaN values are always treated as unequal. - - Two JSON null values are equal. - - @note Floating-point inside JSON values numbers are compared with - `json::number_float_t::operator==` which is `double::operator==` by - default. To compare floating-point while respecting an epsilon, an alternative - [comparison function](https://github.com/mariokonrad/marnav/blob/master/include/marnav/math/floatingpoint.hpp#L34-#L39) - could be used, for instance - @code {.cpp} - template::value, T>::type> - inline bool is_same(T a, T b, T epsilon = std::numeric_limits::epsilon()) noexcept - { - return std::abs(a - b) <= epsilon; - } - @endcode - Or you can self-defined operator equal function like this: - @code {.cpp} - bool my_equal(const_reference lhs, const_reference rhs) { - const auto lhs_type lhs.type(); - const auto rhs_type rhs.type(); - if (lhs_type == rhs_type) { - switch(lhs_type) - // self_defined case - case value_t::number_float: - return std::abs(lhs - rhs) <= std::numeric_limits::epsilon(); - // other cases remain the same with the original - ... - } - ... - } - @endcode - - @note NaN values never compare equal to themselves or to other NaN values. - - @param[in] lhs first JSON value to consider - @param[in] rhs second JSON value to consider - @return whether the values @a lhs and @a rhs are equal - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @complexity Linear. - - @liveexample{The example demonstrates comparing several JSON - types.,operator__equal} - - @since version 1.0.0 - */ - friend bool operator==(const_reference lhs, const_reference rhs) noexcept - { - const auto lhs_type = lhs.type(); - const auto rhs_type = rhs.type(); - - if (lhs_type == rhs_type) - { - switch (lhs_type) - { - case value_t::array: - return *lhs.m_value.array == *rhs.m_value.array; - - case value_t::object: - return *lhs.m_value.object == *rhs.m_value.object; - - case value_t::null: - return true; - - case value_t::string: - return *lhs.m_value.string == *rhs.m_value.string; - - case value_t::boolean: - return lhs.m_value.boolean == rhs.m_value.boolean; - - case value_t::number_integer: - return lhs.m_value.number_integer == rhs.m_value.number_integer; - - case value_t::number_unsigned: - return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned; - - case value_t::number_float: - return lhs.m_value.number_float == rhs.m_value.number_float; - - case value_t::binary: - return *lhs.m_value.binary == *rhs.m_value.binary; - - default: - return false; - } - } - else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float) - { - return static_cast(lhs.m_value.number_integer) == rhs.m_value.number_float; - } - else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer) - { - return lhs.m_value.number_float == static_cast(rhs.m_value.number_integer); - } - else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float) - { - return static_cast(lhs.m_value.number_unsigned) == rhs.m_value.number_float; - } - else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned) - { - return lhs.m_value.number_float == static_cast(rhs.m_value.number_unsigned); - } - else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer) - { - return static_cast(lhs.m_value.number_unsigned) == rhs.m_value.number_integer; - } - else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned) - { - return lhs.m_value.number_integer == static_cast(rhs.m_value.number_unsigned); - } - - return false; - } - - /*! - @brief comparison: equal - @copydoc operator==(const_reference, const_reference) - */ - template::value, int>::type = 0> - friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept - { - return lhs == basic_json(rhs); - } - - /*! - @brief comparison: equal - @copydoc operator==(const_reference, const_reference) - */ - template::value, int>::type = 0> - friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept - { - return basic_json(lhs) == rhs; - } - - /*! - @brief comparison: not equal - - Compares two JSON values for inequality by calculating `not (lhs == rhs)`. - - @param[in] lhs first JSON value to consider - @param[in] rhs second JSON value to consider - @return whether the values @a lhs and @a rhs are not equal - - @complexity Linear. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @liveexample{The example demonstrates comparing several JSON - types.,operator__notequal} - - @since version 1.0.0 - */ - friend bool operator!=(const_reference lhs, const_reference rhs) noexcept - { - return !(lhs == rhs); - } - - /*! - @brief comparison: not equal - @copydoc operator!=(const_reference, const_reference) - */ - template::value, int>::type = 0> - friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept - { - return lhs != basic_json(rhs); - } - - /*! - @brief comparison: not equal - @copydoc operator!=(const_reference, const_reference) - */ - template::value, int>::type = 0> - friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept - { - return basic_json(lhs) != rhs; - } - - /*! - @brief comparison: less than - - Compares whether one JSON value @a lhs is less than another JSON value @a - rhs according to the following rules: - - If @a lhs and @a rhs have the same type, the values are compared using - the default `<` operator. - - Integer and floating-point numbers are automatically converted before - comparison - - In case @a lhs and @a rhs have different types, the values are ignored - and the order of the types is considered, see - @ref operator<(const value_t, const value_t). - - @param[in] lhs first JSON value to consider - @param[in] rhs second JSON value to consider - @return whether @a lhs is less than @a rhs - - @complexity Linear. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @liveexample{The example demonstrates comparing several JSON - types.,operator__less} - - @since version 1.0.0 - */ - friend bool operator<(const_reference lhs, const_reference rhs) noexcept - { - const auto lhs_type = lhs.type(); - const auto rhs_type = rhs.type(); - - if (lhs_type == rhs_type) - { - switch (lhs_type) - { - case value_t::array: - // note parentheses are necessary, see - // https://github.com/nlohmann/json/issues/1530 - return (*lhs.m_value.array) < (*rhs.m_value.array); - - case value_t::object: - return (*lhs.m_value.object) < (*rhs.m_value.object); - - case value_t::null: - return false; - - case value_t::string: - return (*lhs.m_value.string) < (*rhs.m_value.string); - - case value_t::boolean: - return (lhs.m_value.boolean) < (rhs.m_value.boolean); - - case value_t::number_integer: - return (lhs.m_value.number_integer) < (rhs.m_value.number_integer); - - case value_t::number_unsigned: - return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned); - - case value_t::number_float: - return (lhs.m_value.number_float) < (rhs.m_value.number_float); - - case value_t::binary: - return (*lhs.m_value.binary) < (*rhs.m_value.binary); - - default: - return false; - } - } - else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float) - { - return static_cast(lhs.m_value.number_integer) < rhs.m_value.number_float; - } - else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer) - { - return lhs.m_value.number_float < static_cast(rhs.m_value.number_integer); - } - else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float) - { - return static_cast(lhs.m_value.number_unsigned) < rhs.m_value.number_float; - } - else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned) - { - return lhs.m_value.number_float < static_cast(rhs.m_value.number_unsigned); - } - else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned) - { - return lhs.m_value.number_integer < static_cast(rhs.m_value.number_unsigned); - } - else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer) - { - return static_cast(lhs.m_value.number_unsigned) < rhs.m_value.number_integer; - } - - // We only reach this line if we cannot compare values. In that case, - // we compare types. Note we have to call the operator explicitly, - // because MSVC has problems otherwise. - return operator<(lhs_type, rhs_type); - } - - /*! - @brief comparison: less than - @copydoc operator<(const_reference, const_reference) - */ - template::value, int>::type = 0> - friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept - { - return lhs < basic_json(rhs); - } - - /*! - @brief comparison: less than - @copydoc operator<(const_reference, const_reference) - */ - template::value, int>::type = 0> - friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept - { - return basic_json(lhs) < rhs; - } - - /*! - @brief comparison: less than or equal - - Compares whether one JSON value @a lhs is less than or equal to another - JSON value by calculating `not (rhs < lhs)`. - - @param[in] lhs first JSON value to consider - @param[in] rhs second JSON value to consider - @return whether @a lhs is less than or equal to @a rhs - - @complexity Linear. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @liveexample{The example demonstrates comparing several JSON - types.,operator__greater} - - @since version 1.0.0 - */ - friend bool operator<=(const_reference lhs, const_reference rhs) noexcept - { - return !(rhs < lhs); - } - - /*! - @brief comparison: less than or equal - @copydoc operator<=(const_reference, const_reference) - */ - template::value, int>::type = 0> - friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept - { - return lhs <= basic_json(rhs); - } - - /*! - @brief comparison: less than or equal - @copydoc operator<=(const_reference, const_reference) - */ - template::value, int>::type = 0> - friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept - { - return basic_json(lhs) <= rhs; - } - - /*! - @brief comparison: greater than - - Compares whether one JSON value @a lhs is greater than another - JSON value by calculating `not (lhs <= rhs)`. - - @param[in] lhs first JSON value to consider - @param[in] rhs second JSON value to consider - @return whether @a lhs is greater than to @a rhs - - @complexity Linear. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @liveexample{The example demonstrates comparing several JSON - types.,operator__lessequal} - - @since version 1.0.0 - */ - friend bool operator>(const_reference lhs, const_reference rhs) noexcept - { - return !(lhs <= rhs); - } - - /*! - @brief comparison: greater than - @copydoc operator>(const_reference, const_reference) - */ - template::value, int>::type = 0> - friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept - { - return lhs > basic_json(rhs); - } - - /*! - @brief comparison: greater than - @copydoc operator>(const_reference, const_reference) - */ - template::value, int>::type = 0> - friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept - { - return basic_json(lhs) > rhs; - } - - /*! - @brief comparison: greater than or equal - - Compares whether one JSON value @a lhs is greater than or equal to another - JSON value by calculating `not (lhs < rhs)`. - - @param[in] lhs first JSON value to consider - @param[in] rhs second JSON value to consider - @return whether @a lhs is greater than or equal to @a rhs - - @complexity Linear. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @liveexample{The example demonstrates comparing several JSON - types.,operator__greaterequal} - - @since version 1.0.0 - */ - friend bool operator>=(const_reference lhs, const_reference rhs) noexcept - { - return !(lhs < rhs); - } - - /*! - @brief comparison: greater than or equal - @copydoc operator>=(const_reference, const_reference) - */ - template::value, int>::type = 0> - friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept - { - return lhs >= basic_json(rhs); - } - - /*! - @brief comparison: greater than or equal - @copydoc operator>=(const_reference, const_reference) - */ - template::value, int>::type = 0> - friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept - { - return basic_json(lhs) >= rhs; - } - - /// @} - - /////////////////// - // serialization // - /////////////////// - - /// @name serialization - /// @{ - - /*! - @brief serialize to stream - - Serialize the given JSON value @a j to the output stream @a o. The JSON - value will be serialized using the @ref dump member function. - - - The indentation of the output can be controlled with the member variable - `width` of the output stream @a o. For instance, using the manipulator - `std::setw(4)` on @a o sets the indentation level to `4` and the - serialization result is the same as calling `dump(4)`. - - - The indentation character can be controlled with the member variable - `fill` of the output stream @a o. For instance, the manipulator - `std::setfill('\\t')` sets indentation to use a tab character rather than - the default space character. - - @param[in,out] o stream to serialize to - @param[in] j JSON value to serialize - - @return the stream @a o - - @throw type_error.316 if a string stored inside the JSON value is not - UTF-8 encoded - - @complexity Linear. - - @liveexample{The example below shows the serialization with different - parameters to `width` to adjust the indentation level.,operator_serialize} - - @since version 1.0.0; indentation character added in version 3.0.0 - */ - friend std::ostream& operator<<(std::ostream& o, const basic_json& j) - { - // read width member and use it as indentation parameter if nonzero - const bool pretty_print = o.width() > 0; - const auto indentation = pretty_print ? o.width() : 0; - - // reset width to 0 for subsequent calls to this stream - o.width(0); - - // do the actual serialization - serializer s(detail::output_adapter(o), o.fill()); - s.dump(j, pretty_print, false, static_cast(indentation)); - return o; - } - - /*! - @brief serialize to stream - @deprecated This stream operator is deprecated and will be removed in - future 4.0.0 of the library. Please use - @ref operator<<(std::ostream&, const basic_json&) - instead; that is, replace calls like `j >> o;` with `o << j;`. - @since version 1.0.0; deprecated since version 3.0.0 - */ - JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&)) - friend std::ostream& operator>>(const basic_json& j, std::ostream& o) - { - return o << j; - } - - /// @} - - - ///////////////////// - // deserialization // - ///////////////////// - - /// @name deserialization - /// @{ - - /*! - @brief deserialize from a compatible input - - @tparam InputType A compatible input, for instance - - an std::istream object - - a FILE pointer - - a C-style array of characters - - a pointer to a null-terminated string of single byte characters - - an object obj for which begin(obj) and end(obj) produces a valid pair of - iterators. - - @param[in] i input to read from - @param[in] cb a parser callback function of type @ref parser_callback_t - which is used to control the deserialization by filtering unwanted values - (optional) - @param[in] allow_exceptions whether to throw exceptions in case of a - parse error (optional, true by default) - @param[in] ignore_comments whether comments should be ignored and treated - like whitespace (true) or yield a parse error (true); (optional, false by - default) - - @return deserialized JSON value; in case of a parse error and - @a allow_exceptions set to `false`, the return value will be - value_t::discarded. - - @throw parse_error.101 if a parse error occurs; example: `""unexpected end - of input; expected string literal""` - @throw parse_error.102 if to_unicode fails or surrogate error - @throw parse_error.103 if to_unicode fails - - @complexity Linear in the length of the input. The parser is a predictive - LL(1) parser. The complexity can be higher if the parser callback function - @a cb or reading from the input @a i has a super-linear complexity. - - @note A UTF-8 byte order mark is silently ignored. - - @liveexample{The example below demonstrates the `parse()` function reading - from an array.,parse__array__parser_callback_t} - - @liveexample{The example below demonstrates the `parse()` function with - and without callback function.,parse__string__parser_callback_t} - - @liveexample{The example below demonstrates the `parse()` function with - and without callback function.,parse__istream__parser_callback_t} - - @liveexample{The example below demonstrates the `parse()` function reading - from a contiguous container.,parse__contiguouscontainer__parser_callback_t} - - @since version 2.0.3 (contiguous containers); version 3.9.0 allowed to - ignore comments. - */ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json parse(InputType&& i, - const parser_callback_t cb = nullptr, - const bool allow_exceptions = true, - const bool ignore_comments = false) - { - basic_json result; - parser(detail::input_adapter(std::forward(i)), cb, allow_exceptions, ignore_comments).parse(true, result); - return result; - } - - /*! - @brief deserialize from a pair of character iterators - - The value_type of the iterator must be a integral type with size of 1, 2 or - 4 bytes, which will be interpreted respectively as UTF-8, UTF-16 and UTF-32. - - @param[in] first iterator to start of character range - @param[in] last iterator to end of character range - @param[in] cb a parser callback function of type @ref parser_callback_t - which is used to control the deserialization by filtering unwanted values - (optional) - @param[in] allow_exceptions whether to throw exceptions in case of a - parse error (optional, true by default) - @param[in] ignore_comments whether comments should be ignored and treated - like whitespace (true) or yield a parse error (true); (optional, false by - default) - - @return deserialized JSON value; in case of a parse error and - @a allow_exceptions set to `false`, the return value will be - value_t::discarded. - - @throw parse_error.101 if a parse error occurs; example: `""unexpected end - of input; expected string literal""` - @throw parse_error.102 if to_unicode fails or surrogate error - @throw parse_error.103 if to_unicode fails - */ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json parse(IteratorType first, - IteratorType last, - const parser_callback_t cb = nullptr, - const bool allow_exceptions = true, - const bool ignore_comments = false) - { - basic_json result; - parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result); - return result; - } - - JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len)) - static basic_json parse(detail::span_input_adapter&& i, - const parser_callback_t cb = nullptr, - const bool allow_exceptions = true, - const bool ignore_comments = false) - { - basic_json result; - parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result); - return result; - } - - /*! - @brief check if the input is valid JSON - - Unlike the @ref parse(InputType&&, const parser_callback_t,const bool) - function, this function neither throws an exception in case of invalid JSON - input (i.e., a parse error) nor creates diagnostic information. - - @tparam InputType A compatible input, for instance - - an std::istream object - - a FILE pointer - - a C-style array of characters - - a pointer to a null-terminated string of single byte characters - - an object obj for which begin(obj) and end(obj) produces a valid pair of - iterators. - - @param[in] i input to read from - @param[in] ignore_comments whether comments should be ignored and treated - like whitespace (true) or yield a parse error (true); (optional, false by - default) - - @return Whether the input read from @a i is valid JSON. - - @complexity Linear in the length of the input. The parser is a predictive - LL(1) parser. - - @note A UTF-8 byte order mark is silently ignored. - - @liveexample{The example below demonstrates the `accept()` function reading - from a string.,accept__string} - */ - template - static bool accept(InputType&& i, - const bool ignore_comments = false) - { - return parser(detail::input_adapter(std::forward(i)), nullptr, false, ignore_comments).accept(true); - } - - template - static bool accept(IteratorType first, IteratorType last, - const bool ignore_comments = false) - { - return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true); - } - - JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len)) - static bool accept(detail::span_input_adapter&& i, - const bool ignore_comments = false) - { - return parser(i.get(), nullptr, false, ignore_comments).accept(true); - } - - /*! - @brief generate SAX events - - The SAX event lister must follow the interface of @ref json_sax. - - This function reads from a compatible input. Examples are: - - an std::istream object - - a FILE pointer - - a C-style array of characters - - a pointer to a null-terminated string of single byte characters - - an object obj for which begin(obj) and end(obj) produces a valid pair of - iterators. - - @param[in] i input to read from - @param[in,out] sax SAX event listener - @param[in] format the format to parse (JSON, CBOR, MessagePack, or UBJSON) - @param[in] strict whether the input has to be consumed completely - @param[in] ignore_comments whether comments should be ignored and treated - like whitespace (true) or yield a parse error (true); (optional, false by - default); only applies to the JSON file format. - - @return return value of the last processed SAX event - - @throw parse_error.101 if a parse error occurs; example: `""unexpected end - of input; expected string literal""` - @throw parse_error.102 if to_unicode fails or surrogate error - @throw parse_error.103 if to_unicode fails - - @complexity Linear in the length of the input. The parser is a predictive - LL(1) parser. The complexity can be higher if the SAX consumer @a sax has - a super-linear complexity. - - @note A UTF-8 byte order mark is silently ignored. - - @liveexample{The example below demonstrates the `sax_parse()` function - reading from string and processing the events with a user-defined SAX - event consumer.,sax_parse} - - @since version 3.2.0 - */ - template - JSON_HEDLEY_NON_NULL(2) - static bool sax_parse(InputType&& i, SAX* sax, - input_format_t format = input_format_t::json, - const bool strict = true, - const bool ignore_comments = false) - { - auto ia = detail::input_adapter(std::forward(i)); - return format == input_format_t::json - ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict) - : detail::binary_reader(std::move(ia)).sax_parse(format, sax, strict); - } - - template - JSON_HEDLEY_NON_NULL(3) - static bool sax_parse(IteratorType first, IteratorType last, SAX* sax, - input_format_t format = input_format_t::json, - const bool strict = true, - const bool ignore_comments = false) - { - auto ia = detail::input_adapter(std::move(first), std::move(last)); - return format == input_format_t::json - ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict) - : detail::binary_reader(std::move(ia)).sax_parse(format, sax, strict); - } - - template - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...)) - JSON_HEDLEY_NON_NULL(2) - static bool sax_parse(detail::span_input_adapter&& i, SAX* sax, - input_format_t format = input_format_t::json, - const bool strict = true, - const bool ignore_comments = false) - { - auto ia = i.get(); - return format == input_format_t::json - ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict) - : detail::binary_reader(std::move(ia)).sax_parse(format, sax, strict); - } - - /*! - @brief deserialize from stream - @deprecated This stream operator is deprecated and will be removed in - version 4.0.0 of the library. Please use - @ref operator>>(std::istream&, basic_json&) - instead; that is, replace calls like `j << i;` with `i >> j;`. - @since version 1.0.0; deprecated since version 3.0.0 - */ - JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&)) - friend std::istream& operator<<(basic_json& j, std::istream& i) - { - return operator>>(i, j); - } - - /*! - @brief deserialize from stream - - Deserializes an input stream to a JSON value. - - @param[in,out] i input stream to read a serialized JSON value from - @param[in,out] j JSON value to write the deserialized input to - - @throw parse_error.101 in case of an unexpected token - @throw parse_error.102 if to_unicode fails or surrogate error - @throw parse_error.103 if to_unicode fails - - @complexity Linear in the length of the input. The parser is a predictive - LL(1) parser. - - @note A UTF-8 byte order mark is silently ignored. - - @liveexample{The example below shows how a JSON value is constructed by - reading a serialization from a stream.,operator_deserialize} - - @sa parse(std::istream&, const parser_callback_t) for a variant with a - parser callback function to filter values while parsing - - @since version 1.0.0 - */ - friend std::istream& operator>>(std::istream& i, basic_json& j) - { - parser(detail::input_adapter(i)).parse(false, j); - return i; - } - - /// @} - - /////////////////////////// - // convenience functions // - /////////////////////////// - - /*! - @brief return the type as string - - Returns the type name as string to be used in error messages - usually to - indicate that a function was called on a wrong JSON type. - - @return a string representation of a the @a m_type member: - Value type | return value - ----------- | ------------- - null | `"null"` - boolean | `"boolean"` - string | `"string"` - number | `"number"` (for all number types) - object | `"object"` - array | `"array"` - binary | `"binary"` - discarded | `"discarded"` - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @complexity Constant. - - @liveexample{The following code exemplifies `type_name()` for all JSON - types.,type_name} - - @sa @ref type() -- return the type of the JSON value - @sa @ref operator value_t() -- return the type of the JSON value (implicit) - - @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept` - since 3.0.0 - */ - JSON_HEDLEY_RETURNS_NON_NULL - const char* type_name() const noexcept - { - { - switch (m_type) - { - case value_t::null: - return "null"; - case value_t::object: - return "object"; - case value_t::array: - return "array"; - case value_t::string: - return "string"; - case value_t::boolean: - return "boolean"; - case value_t::binary: - return "binary"; - case value_t::discarded: - return "discarded"; - default: - return "number"; - } - } - } - - - private: - ////////////////////// - // member variables // - ////////////////////// - - /// the type of the current element - value_t m_type = value_t::null; - - /// the value of the current element - json_value m_value = {}; - - ////////////////////////////////////////// - // binary serialization/deserialization // - ////////////////////////////////////////// - - /// @name binary serialization/deserialization support - /// @{ - - public: - /*! - @brief create a CBOR serialization of a given JSON value - - Serializes a given JSON value @a j to a byte vector using the CBOR (Concise - Binary Object Representation) serialization format. CBOR is a binary - serialization format which aims to be more compact than JSON itself, yet - more efficient to parse. - - The library uses the following mapping from JSON values types to - CBOR types according to the CBOR specification (RFC 7049): - - JSON value type | value/range | CBOR type | first byte - --------------- | ------------------------------------------ | ---------------------------------- | --------------- - null | `null` | Null | 0xF6 - boolean | `true` | True | 0xF5 - boolean | `false` | False | 0xF4 - number_integer | -9223372036854775808..-2147483649 | Negative integer (8 bytes follow) | 0x3B - number_integer | -2147483648..-32769 | Negative integer (4 bytes follow) | 0x3A - number_integer | -32768..-129 | Negative integer (2 bytes follow) | 0x39 - number_integer | -128..-25 | Negative integer (1 byte follow) | 0x38 - number_integer | -24..-1 | Negative integer | 0x20..0x37 - number_integer | 0..23 | Integer | 0x00..0x17 - number_integer | 24..255 | Unsigned integer (1 byte follow) | 0x18 - number_integer | 256..65535 | Unsigned integer (2 bytes follow) | 0x19 - number_integer | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A - number_integer | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B - number_unsigned | 0..23 | Integer | 0x00..0x17 - number_unsigned | 24..255 | Unsigned integer (1 byte follow) | 0x18 - number_unsigned | 256..65535 | Unsigned integer (2 bytes follow) | 0x19 - number_unsigned | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A - number_unsigned | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B - number_float | *any value representable by a float* | Single-Precision Float | 0xFA - number_float | *any value NOT representable by a float* | Double-Precision Float | 0xFB - string | *length*: 0..23 | UTF-8 string | 0x60..0x77 - string | *length*: 23..255 | UTF-8 string (1 byte follow) | 0x78 - string | *length*: 256..65535 | UTF-8 string (2 bytes follow) | 0x79 - string | *length*: 65536..4294967295 | UTF-8 string (4 bytes follow) | 0x7A - string | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow) | 0x7B - array | *size*: 0..23 | array | 0x80..0x97 - array | *size*: 23..255 | array (1 byte follow) | 0x98 - array | *size*: 256..65535 | array (2 bytes follow) | 0x99 - array | *size*: 65536..4294967295 | array (4 bytes follow) | 0x9A - array | *size*: 4294967296..18446744073709551615 | array (8 bytes follow) | 0x9B - object | *size*: 0..23 | map | 0xA0..0xB7 - object | *size*: 23..255 | map (1 byte follow) | 0xB8 - object | *size*: 256..65535 | map (2 bytes follow) | 0xB9 - object | *size*: 65536..4294967295 | map (4 bytes follow) | 0xBA - object | *size*: 4294967296..18446744073709551615 | map (8 bytes follow) | 0xBB - binary | *size*: 0..23 | byte string | 0x40..0x57 - binary | *size*: 23..255 | byte string (1 byte follow) | 0x58 - binary | *size*: 256..65535 | byte string (2 bytes follow) | 0x59 - binary | *size*: 65536..4294967295 | byte string (4 bytes follow) | 0x5A - binary | *size*: 4294967296..18446744073709551615 | byte string (8 bytes follow) | 0x5B - - @note The mapping is **complete** in the sense that any JSON value type - can be converted to a CBOR value. - - @note If NaN or Infinity are stored inside a JSON number, they are - serialized properly. This behavior differs from the @ref dump() - function which serializes NaN or Infinity to `null`. - - @note The following CBOR types are not used in the conversion: - - UTF-8 strings terminated by "break" (0x7F) - - arrays terminated by "break" (0x9F) - - maps terminated by "break" (0xBF) - - byte strings terminated by "break" (0x5F) - - date/time (0xC0..0xC1) - - bignum (0xC2..0xC3) - - decimal fraction (0xC4) - - bigfloat (0xC5) - - expected conversions (0xD5..0xD7) - - simple values (0xE0..0xF3, 0xF8) - - undefined (0xF7) - - half-precision floats (0xF9) - - break (0xFF) - - @param[in] j JSON value to serialize - @return CBOR serialization as byte vector - - @complexity Linear in the size of the JSON value @a j. - - @liveexample{The example shows the serialization of a JSON value to a byte - vector in CBOR format.,to_cbor} - - @sa http://cbor.io - @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t) for the - analogous deserialization - @sa @ref to_msgpack(const basic_json&) for the related MessagePack format - @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the - related UBJSON format - - @since version 2.0.9; compact representation of floating-point numbers - since version 3.8.0 - */ - static std::vector to_cbor(const basic_json& j) - { - std::vector result; - to_cbor(j, result); - return result; - } - - static void to_cbor(const basic_json& j, detail::output_adapter o) - { - binary_writer(o).write_cbor(j); - } - - static void to_cbor(const basic_json& j, detail::output_adapter o) - { - binary_writer(o).write_cbor(j); - } - - /*! - @brief create a MessagePack serialization of a given JSON value - - Serializes a given JSON value @a j to a byte vector using the MessagePack - serialization format. MessagePack is a binary serialization format which - aims to be more compact than JSON itself, yet more efficient to parse. - - The library uses the following mapping from JSON values types to - MessagePack types according to the MessagePack specification: - - JSON value type | value/range | MessagePack type | first byte - --------------- | --------------------------------- | ---------------- | ---------- - null | `null` | nil | 0xC0 - boolean | `true` | true | 0xC3 - boolean | `false` | false | 0xC2 - number_integer | -9223372036854775808..-2147483649 | int64 | 0xD3 - number_integer | -2147483648..-32769 | int32 | 0xD2 - number_integer | -32768..-129 | int16 | 0xD1 - number_integer | -128..-33 | int8 | 0xD0 - number_integer | -32..-1 | negative fixint | 0xE0..0xFF - number_integer | 0..127 | positive fixint | 0x00..0x7F - number_integer | 128..255 | uint 8 | 0xCC - number_integer | 256..65535 | uint 16 | 0xCD - number_integer | 65536..4294967295 | uint 32 | 0xCE - number_integer | 4294967296..18446744073709551615 | uint 64 | 0xCF - number_unsigned | 0..127 | positive fixint | 0x00..0x7F - number_unsigned | 128..255 | uint 8 | 0xCC - number_unsigned | 256..65535 | uint 16 | 0xCD - number_unsigned | 65536..4294967295 | uint 32 | 0xCE - number_unsigned | 4294967296..18446744073709551615 | uint 64 | 0xCF - number_float | *any value representable by a float* | float 32 | 0xCA - number_float | *any value NOT representable by a float* | float 64 | 0xCB - string | *length*: 0..31 | fixstr | 0xA0..0xBF - string | *length*: 32..255 | str 8 | 0xD9 - string | *length*: 256..65535 | str 16 | 0xDA - string | *length*: 65536..4294967295 | str 32 | 0xDB - array | *size*: 0..15 | fixarray | 0x90..0x9F - array | *size*: 16..65535 | array 16 | 0xDC - array | *size*: 65536..4294967295 | array 32 | 0xDD - object | *size*: 0..15 | fix map | 0x80..0x8F - object | *size*: 16..65535 | map 16 | 0xDE - object | *size*: 65536..4294967295 | map 32 | 0xDF - binary | *size*: 0..255 | bin 8 | 0xC4 - binary | *size*: 256..65535 | bin 16 | 0xC5 - binary | *size*: 65536..4294967295 | bin 32 | 0xC6 - - @note The mapping is **complete** in the sense that any JSON value type - can be converted to a MessagePack value. - - @note The following values can **not** be converted to a MessagePack value: - - strings with more than 4294967295 bytes - - byte strings with more than 4294967295 bytes - - arrays with more than 4294967295 elements - - objects with more than 4294967295 elements - - @note Any MessagePack output created @ref to_msgpack can be successfully - parsed by @ref from_msgpack. - - @note If NaN or Infinity are stored inside a JSON number, they are - serialized properly. This behavior differs from the @ref dump() - function which serializes NaN or Infinity to `null`. - - @param[in] j JSON value to serialize - @return MessagePack serialization as byte vector - - @complexity Linear in the size of the JSON value @a j. - - @liveexample{The example shows the serialization of a JSON value to a byte - vector in MessagePack format.,to_msgpack} - - @sa http://msgpack.org - @sa @ref from_msgpack for the analogous deserialization - @sa @ref to_cbor(const basic_json& for the related CBOR format - @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the - related UBJSON format - - @since version 2.0.9 - */ - static std::vector to_msgpack(const basic_json& j) - { - std::vector result; - to_msgpack(j, result); - return result; - } - - static void to_msgpack(const basic_json& j, detail::output_adapter o) - { - binary_writer(o).write_msgpack(j); - } - - static void to_msgpack(const basic_json& j, detail::output_adapter o) - { - binary_writer(o).write_msgpack(j); - } - - /*! - @brief create a UBJSON serialization of a given JSON value - - Serializes a given JSON value @a j to a byte vector using the UBJSON - (Universal Binary JSON) serialization format. UBJSON aims to be more compact - than JSON itself, yet more efficient to parse. - - The library uses the following mapping from JSON values types to - UBJSON types according to the UBJSON specification: - - JSON value type | value/range | UBJSON type | marker - --------------- | --------------------------------- | ----------- | ------ - null | `null` | null | `Z` - boolean | `true` | true | `T` - boolean | `false` | false | `F` - number_integer | -9223372036854775808..-2147483649 | int64 | `L` - number_integer | -2147483648..-32769 | int32 | `l` - number_integer | -32768..-129 | int16 | `I` - number_integer | -128..127 | int8 | `i` - number_integer | 128..255 | uint8 | `U` - number_integer | 256..32767 | int16 | `I` - number_integer | 32768..2147483647 | int32 | `l` - number_integer | 2147483648..9223372036854775807 | int64 | `L` - number_unsigned | 0..127 | int8 | `i` - number_unsigned | 128..255 | uint8 | `U` - number_unsigned | 256..32767 | int16 | `I` - number_unsigned | 32768..2147483647 | int32 | `l` - number_unsigned | 2147483648..9223372036854775807 | int64 | `L` - number_unsigned | 2147483649..18446744073709551615 | high-precision | `H` - number_float | *any value* | float64 | `D` - string | *with shortest length indicator* | string | `S` - array | *see notes on optimized format* | array | `[` - object | *see notes on optimized format* | map | `{` - - @note The mapping is **complete** in the sense that any JSON value type - can be converted to a UBJSON value. - - @note The following values can **not** be converted to a UBJSON value: - - strings with more than 9223372036854775807 bytes (theoretical) - - @note The following markers are not used in the conversion: - - `Z`: no-op values are not created. - - `C`: single-byte strings are serialized with `S` markers. - - @note Any UBJSON output created @ref to_ubjson can be successfully parsed - by @ref from_ubjson. - - @note If NaN or Infinity are stored inside a JSON number, they are - serialized properly. This behavior differs from the @ref dump() - function which serializes NaN or Infinity to `null`. - - @note The optimized formats for containers are supported: Parameter - @a use_size adds size information to the beginning of a container and - removes the closing marker. Parameter @a use_type further checks - whether all elements of a container have the same type and adds the - type marker to the beginning of the container. The @a use_type - parameter must only be used together with @a use_size = true. Note - that @a use_size = true alone may result in larger representations - - the benefit of this parameter is that the receiving side is - immediately informed on the number of elements of the container. - - @note If the JSON data contains the binary type, the value stored is a list - of integers, as suggested by the UBJSON documentation. In particular, - this means that serialization and the deserialization of a JSON - containing binary values into UBJSON and back will result in a - different JSON object. - - @param[in] j JSON value to serialize - @param[in] use_size whether to add size annotations to container types - @param[in] use_type whether to add type annotations to container types - (must be combined with @a use_size = true) - @return UBJSON serialization as byte vector - - @complexity Linear in the size of the JSON value @a j. - - @liveexample{The example shows the serialization of a JSON value to a byte - vector in UBJSON format.,to_ubjson} - - @sa http://ubjson.org - @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the - analogous deserialization - @sa @ref to_cbor(const basic_json& for the related CBOR format - @sa @ref to_msgpack(const basic_json&) for the related MessagePack format - - @since version 3.1.0 - */ - static std::vector to_ubjson(const basic_json& j, - const bool use_size = false, - const bool use_type = false) - { - std::vector result; - to_ubjson(j, result, use_size, use_type); - return result; - } - - static void to_ubjson(const basic_json& j, detail::output_adapter o, - const bool use_size = false, const bool use_type = false) - { - binary_writer(o).write_ubjson(j, use_size, use_type); - } - - static void to_ubjson(const basic_json& j, detail::output_adapter o, - const bool use_size = false, const bool use_type = false) - { - binary_writer(o).write_ubjson(j, use_size, use_type); - } - - - /*! - @brief Serializes the given JSON object `j` to BSON and returns a vector - containing the corresponding BSON-representation. - - BSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are - stored as a single entity (a so-called document). - - The library uses the following mapping from JSON values types to BSON types: - - JSON value type | value/range | BSON type | marker - --------------- | --------------------------------- | ----------- | ------ - null | `null` | null | 0x0A - boolean | `true`, `false` | boolean | 0x08 - number_integer | -9223372036854775808..-2147483649 | int64 | 0x12 - number_integer | -2147483648..2147483647 | int32 | 0x10 - number_integer | 2147483648..9223372036854775807 | int64 | 0x12 - number_unsigned | 0..2147483647 | int32 | 0x10 - number_unsigned | 2147483648..9223372036854775807 | int64 | 0x12 - number_unsigned | 9223372036854775808..18446744073709551615| -- | -- - number_float | *any value* | double | 0x01 - string | *any value* | string | 0x02 - array | *any value* | document | 0x04 - object | *any value* | document | 0x03 - binary | *any value* | binary | 0x05 - - @warning The mapping is **incomplete**, since only JSON-objects (and things - contained therein) can be serialized to BSON. - Also, integers larger than 9223372036854775807 cannot be serialized to BSON, - and the keys may not contain U+0000, since they are serialized a - zero-terminated c-strings. - - @throw out_of_range.407 if `j.is_number_unsigned() && j.get() > 9223372036854775807` - @throw out_of_range.409 if a key in `j` contains a NULL (U+0000) - @throw type_error.317 if `!j.is_object()` - - @pre The input `j` is required to be an object: `j.is_object() == true`. - - @note Any BSON output created via @ref to_bson can be successfully parsed - by @ref from_bson. - - @param[in] j JSON value to serialize - @return BSON serialization as byte vector - - @complexity Linear in the size of the JSON value @a j. - - @liveexample{The example shows the serialization of a JSON value to a byte - vector in BSON format.,to_bson} - - @sa http://bsonspec.org/spec.html - @sa @ref from_bson(detail::input_adapter&&, const bool strict) for the - analogous deserialization - @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the - related UBJSON format - @sa @ref to_cbor(const basic_json&) for the related CBOR format - @sa @ref to_msgpack(const basic_json&) for the related MessagePack format - */ - static std::vector to_bson(const basic_json& j) - { - std::vector result; - to_bson(j, result); - return result; - } - - /*! - @brief Serializes the given JSON object `j` to BSON and forwards the - corresponding BSON-representation to the given output_adapter `o`. - @param j The JSON object to convert to BSON. - @param o The output adapter that receives the binary BSON representation. - @pre The input `j` shall be an object: `j.is_object() == true` - @sa @ref to_bson(const basic_json&) - */ - static void to_bson(const basic_json& j, detail::output_adapter o) - { - binary_writer(o).write_bson(j); - } - - /*! - @copydoc to_bson(const basic_json&, detail::output_adapter) - */ - static void to_bson(const basic_json& j, detail::output_adapter o) - { - binary_writer(o).write_bson(j); - } - - - /*! - @brief create a JSON value from an input in CBOR format - - Deserializes a given input @a i to a JSON value using the CBOR (Concise - Binary Object Representation) serialization format. - - The library maps CBOR types to JSON value types as follows: - - CBOR type | JSON value type | first byte - ---------------------- | --------------- | ---------- - Integer | number_unsigned | 0x00..0x17 - Unsigned integer | number_unsigned | 0x18 - Unsigned integer | number_unsigned | 0x19 - Unsigned integer | number_unsigned | 0x1A - Unsigned integer | number_unsigned | 0x1B - Negative integer | number_integer | 0x20..0x37 - Negative integer | number_integer | 0x38 - Negative integer | number_integer | 0x39 - Negative integer | number_integer | 0x3A - Negative integer | number_integer | 0x3B - Byte string | binary | 0x40..0x57 - Byte string | binary | 0x58 - Byte string | binary | 0x59 - Byte string | binary | 0x5A - Byte string | binary | 0x5B - UTF-8 string | string | 0x60..0x77 - UTF-8 string | string | 0x78 - UTF-8 string | string | 0x79 - UTF-8 string | string | 0x7A - UTF-8 string | string | 0x7B - UTF-8 string | string | 0x7F - array | array | 0x80..0x97 - array | array | 0x98 - array | array | 0x99 - array | array | 0x9A - array | array | 0x9B - array | array | 0x9F - map | object | 0xA0..0xB7 - map | object | 0xB8 - map | object | 0xB9 - map | object | 0xBA - map | object | 0xBB - map | object | 0xBF - False | `false` | 0xF4 - True | `true` | 0xF5 - Null | `null` | 0xF6 - Half-Precision Float | number_float | 0xF9 - Single-Precision Float | number_float | 0xFA - Double-Precision Float | number_float | 0xFB - - @warning The mapping is **incomplete** in the sense that not all CBOR - types can be converted to a JSON value. The following CBOR types - are not supported and will yield parse errors (parse_error.112): - - date/time (0xC0..0xC1) - - bignum (0xC2..0xC3) - - decimal fraction (0xC4) - - bigfloat (0xC5) - - expected conversions (0xD5..0xD7) - - simple values (0xE0..0xF3, 0xF8) - - undefined (0xF7) - - @warning CBOR allows map keys of any type, whereas JSON only allows - strings as keys in object values. Therefore, CBOR maps with keys - other than UTF-8 strings are rejected (parse_error.113). - - @note Any CBOR output created @ref to_cbor can be successfully parsed by - @ref from_cbor. - - @param[in] i an input in CBOR format convertible to an input adapter - @param[in] strict whether to expect the input to be consumed until EOF - (true by default) - @param[in] allow_exceptions whether to throw exceptions in case of a - parse error (optional, true by default) - @param[in] tag_handler how to treat CBOR tags (optional, error by default) - - @return deserialized JSON value; in case of a parse error and - @a allow_exceptions set to `false`, the return value will be - value_t::discarded. - - @throw parse_error.110 if the given input ends prematurely or the end of - file was not reached when @a strict was set to true - @throw parse_error.112 if unsupported features from CBOR were - used in the given input @a v or if the input is not valid CBOR - @throw parse_error.113 if a string was expected as map key, but not found - - @complexity Linear in the size of the input @a i. - - @liveexample{The example shows the deserialization of a byte vector in CBOR - format to a JSON value.,from_cbor} - - @sa http://cbor.io - @sa @ref to_cbor(const basic_json&) for the analogous serialization - @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for the - related MessagePack format - @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the - related UBJSON format - - @since version 2.0.9; parameter @a start_index since 2.1.1; changed to - consume input adapters, removed start_index parameter, and added - @a strict parameter since 3.0.0; added @a allow_exceptions parameter - since 3.2.0; added @a tag_handler parameter since 3.9.0. - */ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_cbor(InputType&& i, - const bool strict = true, - const bool allow_exceptions = true, - const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) - { - basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); - auto ia = detail::input_adapter(std::forward(i)); - const bool res = binary_reader(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler); - return res ? result : basic_json(value_t::discarded); - } - - /*! - @copydoc from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t) - */ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_cbor(IteratorType first, IteratorType last, - const bool strict = true, - const bool allow_exceptions = true, - const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) - { - basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); - auto ia = detail::input_adapter(std::move(first), std::move(last)); - const bool res = binary_reader(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler); - return res ? result : basic_json(value_t::discarded); - } - - template - JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len)) - static basic_json from_cbor(const T* ptr, std::size_t len, - const bool strict = true, - const bool allow_exceptions = true, - const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) - { - return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler); - } - - - JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len)) - static basic_json from_cbor(detail::span_input_adapter&& i, - const bool strict = true, - const bool allow_exceptions = true, - const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) - { - basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); - auto ia = i.get(); - const bool res = binary_reader(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler); - return res ? result : basic_json(value_t::discarded); - } - - /*! - @brief create a JSON value from an input in MessagePack format - - Deserializes a given input @a i to a JSON value using the MessagePack - serialization format. - - The library maps MessagePack types to JSON value types as follows: - - MessagePack type | JSON value type | first byte - ---------------- | --------------- | ---------- - positive fixint | number_unsigned | 0x00..0x7F - fixmap | object | 0x80..0x8F - fixarray | array | 0x90..0x9F - fixstr | string | 0xA0..0xBF - nil | `null` | 0xC0 - false | `false` | 0xC2 - true | `true` | 0xC3 - float 32 | number_float | 0xCA - float 64 | number_float | 0xCB - uint 8 | number_unsigned | 0xCC - uint 16 | number_unsigned | 0xCD - uint 32 | number_unsigned | 0xCE - uint 64 | number_unsigned | 0xCF - int 8 | number_integer | 0xD0 - int 16 | number_integer | 0xD1 - int 32 | number_integer | 0xD2 - int 64 | number_integer | 0xD3 - str 8 | string | 0xD9 - str 16 | string | 0xDA - str 32 | string | 0xDB - array 16 | array | 0xDC - array 32 | array | 0xDD - map 16 | object | 0xDE - map 32 | object | 0xDF - bin 8 | binary | 0xC4 - bin 16 | binary | 0xC5 - bin 32 | binary | 0xC6 - ext 8 | binary | 0xC7 - ext 16 | binary | 0xC8 - ext 32 | binary | 0xC9 - fixext 1 | binary | 0xD4 - fixext 2 | binary | 0xD5 - fixext 4 | binary | 0xD6 - fixext 8 | binary | 0xD7 - fixext 16 | binary | 0xD8 - negative fixint | number_integer | 0xE0-0xFF - - @note Any MessagePack output created @ref to_msgpack can be successfully - parsed by @ref from_msgpack. - - @param[in] i an input in MessagePack format convertible to an input - adapter - @param[in] strict whether to expect the input to be consumed until EOF - (true by default) - @param[in] allow_exceptions whether to throw exceptions in case of a - parse error (optional, true by default) - - @return deserialized JSON value; in case of a parse error and - @a allow_exceptions set to `false`, the return value will be - value_t::discarded. - - @throw parse_error.110 if the given input ends prematurely or the end of - file was not reached when @a strict was set to true - @throw parse_error.112 if unsupported features from MessagePack were - used in the given input @a i or if the input is not valid MessagePack - @throw parse_error.113 if a string was expected as map key, but not found - - @complexity Linear in the size of the input @a i. - - @liveexample{The example shows the deserialization of a byte vector in - MessagePack format to a JSON value.,from_msgpack} - - @sa http://msgpack.org - @sa @ref to_msgpack(const basic_json&) for the analogous serialization - @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t) for the - related CBOR format - @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for - the related UBJSON format - @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for - the related BSON format - - @since version 2.0.9; parameter @a start_index since 2.1.1; changed to - consume input adapters, removed start_index parameter, and added - @a strict parameter since 3.0.0; added @a allow_exceptions parameter - since 3.2.0 - */ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_msgpack(InputType&& i, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); - auto ia = detail::input_adapter(std::forward(i)); - const bool res = binary_reader(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict); - return res ? result : basic_json(value_t::discarded); - } - - /*! - @copydoc from_msgpack(detail::input_adapter&&, const bool, const bool) - */ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_msgpack(IteratorType first, IteratorType last, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); - auto ia = detail::input_adapter(std::move(first), std::move(last)); - const bool res = binary_reader(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict); - return res ? result : basic_json(value_t::discarded); - } - - - template - JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len)) - static basic_json from_msgpack(const T* ptr, std::size_t len, - const bool strict = true, - const bool allow_exceptions = true) - { - return from_msgpack(ptr, ptr + len, strict, allow_exceptions); - } - - JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len)) - static basic_json from_msgpack(detail::span_input_adapter&& i, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); - auto ia = i.get(); - const bool res = binary_reader(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict); - return res ? result : basic_json(value_t::discarded); - } - - - /*! - @brief create a JSON value from an input in UBJSON format - - Deserializes a given input @a i to a JSON value using the UBJSON (Universal - Binary JSON) serialization format. - - The library maps UBJSON types to JSON value types as follows: - - UBJSON type | JSON value type | marker - ----------- | --------------------------------------- | ------ - no-op | *no value, next value is read* | `N` - null | `null` | `Z` - false | `false` | `F` - true | `true` | `T` - float32 | number_float | `d` - float64 | number_float | `D` - uint8 | number_unsigned | `U` - int8 | number_integer | `i` - int16 | number_integer | `I` - int32 | number_integer | `l` - int64 | number_integer | `L` - high-precision number | number_integer, number_unsigned, or number_float - depends on number string | 'H' - string | string | `S` - char | string | `C` - array | array (optimized values are supported) | `[` - object | object (optimized values are supported) | `{` - - @note The mapping is **complete** in the sense that any UBJSON value can - be converted to a JSON value. - - @param[in] i an input in UBJSON format convertible to an input adapter - @param[in] strict whether to expect the input to be consumed until EOF - (true by default) - @param[in] allow_exceptions whether to throw exceptions in case of a - parse error (optional, true by default) - - @return deserialized JSON value; in case of a parse error and - @a allow_exceptions set to `false`, the return value will be - value_t::discarded. - - @throw parse_error.110 if the given input ends prematurely or the end of - file was not reached when @a strict was set to true - @throw parse_error.112 if a parse error occurs - @throw parse_error.113 if a string could not be parsed successfully - - @complexity Linear in the size of the input @a i. - - @liveexample{The example shows the deserialization of a byte vector in - UBJSON format to a JSON value.,from_ubjson} - - @sa http://ubjson.org - @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the - analogous serialization - @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t) for the - related CBOR format - @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for - the related MessagePack format - @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for - the related BSON format - - @since version 3.1.0; added @a allow_exceptions parameter since 3.2.0 - */ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_ubjson(InputType&& i, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); - auto ia = detail::input_adapter(std::forward(i)); - const bool res = binary_reader(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict); - return res ? result : basic_json(value_t::discarded); - } - - /*! - @copydoc from_ubjson(detail::input_adapter&&, const bool, const bool) - */ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_ubjson(IteratorType first, IteratorType last, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); - auto ia = detail::input_adapter(std::move(first), std::move(last)); - const bool res = binary_reader(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict); - return res ? result : basic_json(value_t::discarded); - } - - template - JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len)) - static basic_json from_ubjson(const T* ptr, std::size_t len, - const bool strict = true, - const bool allow_exceptions = true) - { - return from_ubjson(ptr, ptr + len, strict, allow_exceptions); - } - - JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len)) - static basic_json from_ubjson(detail::span_input_adapter&& i, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); - auto ia = i.get(); - const bool res = binary_reader(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict); - return res ? result : basic_json(value_t::discarded); - } - - - /*! - @brief Create a JSON value from an input in BSON format - - Deserializes a given input @a i to a JSON value using the BSON (Binary JSON) - serialization format. - - The library maps BSON record types to JSON value types as follows: - - BSON type | BSON marker byte | JSON value type - --------------- | ---------------- | --------------------------- - double | 0x01 | number_float - string | 0x02 | string - document | 0x03 | object - array | 0x04 | array - binary | 0x05 | still unsupported - undefined | 0x06 | still unsupported - ObjectId | 0x07 | still unsupported - boolean | 0x08 | boolean - UTC Date-Time | 0x09 | still unsupported - null | 0x0A | null - Regular Expr. | 0x0B | still unsupported - DB Pointer | 0x0C | still unsupported - JavaScript Code | 0x0D | still unsupported - Symbol | 0x0E | still unsupported - JavaScript Code | 0x0F | still unsupported - int32 | 0x10 | number_integer - Timestamp | 0x11 | still unsupported - 128-bit decimal float | 0x13 | still unsupported - Max Key | 0x7F | still unsupported - Min Key | 0xFF | still unsupported - - @warning The mapping is **incomplete**. The unsupported mappings - are indicated in the table above. - - @param[in] i an input in BSON format convertible to an input adapter - @param[in] strict whether to expect the input to be consumed until EOF - (true by default) - @param[in] allow_exceptions whether to throw exceptions in case of a - parse error (optional, true by default) - - @return deserialized JSON value; in case of a parse error and - @a allow_exceptions set to `false`, the return value will be - value_t::discarded. - - @throw parse_error.114 if an unsupported BSON record type is encountered - - @complexity Linear in the size of the input @a i. - - @liveexample{The example shows the deserialization of a byte vector in - BSON format to a JSON value.,from_bson} - - @sa http://bsonspec.org/spec.html - @sa @ref to_bson(const basic_json&) for the analogous serialization - @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t) for the - related CBOR format - @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for - the related MessagePack format - @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the - related UBJSON format - */ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_bson(InputType&& i, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); - auto ia = detail::input_adapter(std::forward(i)); - const bool res = binary_reader(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict); - return res ? result : basic_json(value_t::discarded); - } - - /*! - @copydoc from_bson(detail::input_adapter&&, const bool, const bool) - */ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_bson(IteratorType first, IteratorType last, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); - auto ia = detail::input_adapter(std::move(first), std::move(last)); - const bool res = binary_reader(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict); - return res ? result : basic_json(value_t::discarded); - } - - template - JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len)) - static basic_json from_bson(const T* ptr, std::size_t len, - const bool strict = true, - const bool allow_exceptions = true) - { - return from_bson(ptr, ptr + len, strict, allow_exceptions); - } - - JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len)) - static basic_json from_bson(detail::span_input_adapter&& i, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - detail::json_sax_dom_parser sdp(result, allow_exceptions); - auto ia = i.get(); - const bool res = binary_reader(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict); - return res ? result : basic_json(value_t::discarded); - } - /// @} - - ////////////////////////// - // JSON Pointer support // - ////////////////////////// - - /// @name JSON Pointer functions - /// @{ - - /*! - @brief access specified element via JSON Pointer - - Uses a JSON pointer to retrieve a reference to the respective JSON value. - No bound checking is performed. Similar to @ref operator[](const typename - object_t::key_type&), `null` values are created in arrays and objects if - necessary. - - In particular: - - If the JSON pointer points to an object key that does not exist, it - is created an filled with a `null` value before a reference to it - is returned. - - If the JSON pointer points to an array index that does not exist, it - is created an filled with a `null` value before a reference to it - is returned. All indices between the current maximum and the given - index are also filled with `null`. - - The special value `-` is treated as a synonym for the index past the - end. - - @param[in] ptr a JSON pointer - - @return reference to the element pointed to by @a ptr - - @complexity Constant. - - @throw parse_error.106 if an array index begins with '0' - @throw parse_error.109 if an array index was not a number - @throw out_of_range.404 if the JSON pointer can not be resolved - - @liveexample{The behavior is shown in the example.,operatorjson_pointer} - - @since version 2.0.0 - */ - reference operator[](const json_pointer& ptr) - { - return ptr.get_unchecked(this); - } - - /*! - @brief access specified element via JSON Pointer - - Uses a JSON pointer to retrieve a reference to the respective JSON value. - No bound checking is performed. The function does not change the JSON - value; no `null` values are created. In particular, the special value - `-` yields an exception. - - @param[in] ptr JSON pointer to the desired element - - @return const reference to the element pointed to by @a ptr - - @complexity Constant. - - @throw parse_error.106 if an array index begins with '0' - @throw parse_error.109 if an array index was not a number - @throw out_of_range.402 if the array index '-' is used - @throw out_of_range.404 if the JSON pointer can not be resolved - - @liveexample{The behavior is shown in the example.,operatorjson_pointer_const} - - @since version 2.0.0 - */ - const_reference operator[](const json_pointer& ptr) const - { - return ptr.get_unchecked(this); - } - - /*! - @brief access specified element via JSON Pointer - - Returns a reference to the element at with specified JSON pointer @a ptr, - with bounds checking. - - @param[in] ptr JSON pointer to the desired element - - @return reference to the element pointed to by @a ptr - - @throw parse_error.106 if an array index in the passed JSON pointer @a ptr - begins with '0'. See example below. - - @throw parse_error.109 if an array index in the passed JSON pointer @a ptr - is not a number. See example below. - - @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr - is out of range. See example below. - - @throw out_of_range.402 if the array index '-' is used in the passed JSON - pointer @a ptr. As `at` provides checked access (and no elements are - implicitly inserted), the index '-' is always invalid. See example below. - - @throw out_of_range.403 if the JSON pointer describes a key of an object - which cannot be found. See example below. - - @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved. - See example below. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Constant. - - @since version 2.0.0 - - @liveexample{The behavior is shown in the example.,at_json_pointer} - */ - reference at(const json_pointer& ptr) - { - return ptr.get_checked(this); - } - - /*! - @brief access specified element via JSON Pointer - - Returns a const reference to the element at with specified JSON pointer @a - ptr, with bounds checking. - - @param[in] ptr JSON pointer to the desired element - - @return reference to the element pointed to by @a ptr - - @throw parse_error.106 if an array index in the passed JSON pointer @a ptr - begins with '0'. See example below. - - @throw parse_error.109 if an array index in the passed JSON pointer @a ptr - is not a number. See example below. - - @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr - is out of range. See example below. - - @throw out_of_range.402 if the array index '-' is used in the passed JSON - pointer @a ptr. As `at` provides checked access (and no elements are - implicitly inserted), the index '-' is always invalid. See example below. - - @throw out_of_range.403 if the JSON pointer describes a key of an object - which cannot be found. See example below. - - @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved. - See example below. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Constant. - - @since version 2.0.0 - - @liveexample{The behavior is shown in the example.,at_json_pointer_const} - */ - const_reference at(const json_pointer& ptr) const - { - return ptr.get_checked(this); - } - - /*! - @brief return flattened JSON value - - The function creates a JSON object whose keys are JSON pointers (see [RFC - 6901](https://tools.ietf.org/html/rfc6901)) and whose values are all - primitive. The original JSON value can be restored using the @ref - unflatten() function. - - @return an object that maps JSON pointers to primitive values - - @note Empty objects and arrays are flattened to `null` and will not be - reconstructed correctly by the @ref unflatten() function. - - @complexity Linear in the size the JSON value. - - @liveexample{The following code shows how a JSON object is flattened to an - object whose keys consist of JSON pointers.,flatten} - - @sa @ref unflatten() for the reverse function - - @since version 2.0.0 - */ - basic_json flatten() const - { - basic_json result(value_t::object); - json_pointer::flatten("", *this, result); - return result; - } - - /*! - @brief unflatten a previously flattened JSON value - - The function restores the arbitrary nesting of a JSON value that has been - flattened before using the @ref flatten() function. The JSON value must - meet certain constraints: - 1. The value must be an object. - 2. The keys must be JSON pointers (see - [RFC 6901](https://tools.ietf.org/html/rfc6901)) - 3. The mapped values must be primitive JSON types. - - @return the original JSON from a flattened version - - @note Empty objects and arrays are flattened by @ref flatten() to `null` - values and can not unflattened to their original type. Apart from - this example, for a JSON value `j`, the following is always true: - `j == j.flatten().unflatten()`. - - @complexity Linear in the size the JSON value. - - @throw type_error.314 if value is not an object - @throw type_error.315 if object values are not primitive - - @liveexample{The following code shows how a flattened JSON object is - unflattened into the original nested JSON object.,unflatten} - - @sa @ref flatten() for the reverse function - - @since version 2.0.0 - */ - basic_json unflatten() const - { - return json_pointer::unflatten(*this); - } - - /// @} - - ////////////////////////// - // JSON Patch functions // - ////////////////////////// - - /// @name JSON Patch functions - /// @{ - - /*! - @brief applies a JSON patch - - [JSON Patch](http://jsonpatch.com) defines a JSON document structure for - expressing a sequence of operations to apply to a JSON) document. With - this function, a JSON Patch is applied to the current JSON value by - executing all operations from the patch. - - @param[in] json_patch JSON patch document - @return patched document - - @note The application of a patch is atomic: Either all operations succeed - and the patched document is returned or an exception is thrown. In - any case, the original value is not changed: the patch is applied - to a copy of the value. - - @throw parse_error.104 if the JSON patch does not consist of an array of - objects - - @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory - attributes are missing); example: `"operation add must have member path"` - - @throw out_of_range.401 if an array index is out of range. - - @throw out_of_range.403 if a JSON pointer inside the patch could not be - resolved successfully in the current JSON value; example: `"key baz not - found"` - - @throw out_of_range.405 if JSON pointer has no parent ("add", "remove", - "move") - - @throw other_error.501 if "test" operation was unsuccessful - - @complexity Linear in the size of the JSON value and the length of the - JSON patch. As usually only a fraction of the JSON value is affected by - the patch, the complexity can usually be neglected. - - @liveexample{The following code shows how a JSON patch is applied to a - value.,patch} - - @sa @ref diff -- create a JSON patch by comparing two JSON values - - @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902) - @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901) - - @since version 2.0.0 - */ - basic_json patch(const basic_json& json_patch) const - { - // make a working copy to apply the patch to - basic_json result = *this; - - // the valid JSON Patch operations - enum class patch_operations {add, remove, replace, move, copy, test, invalid}; - - const auto get_op = [](const std::string & op) - { - if (op == "add") - { - return patch_operations::add; - } - if (op == "remove") - { - return patch_operations::remove; - } - if (op == "replace") - { - return patch_operations::replace; - } - if (op == "move") - { - return patch_operations::move; - } - if (op == "copy") - { - return patch_operations::copy; - } - if (op == "test") - { - return patch_operations::test; - } - - return patch_operations::invalid; - }; - - // wrapper for "add" operation; add value at ptr - const auto operation_add = [&result](json_pointer & ptr, basic_json val) - { - // adding to the root of the target document means replacing it - if (ptr.empty()) - { - result = val; - return; - } - - // make sure the top element of the pointer exists - json_pointer top_pointer = ptr.top(); - if (top_pointer != ptr) - { - result.at(top_pointer); - } - - // get reference to parent of JSON pointer ptr - const auto last_path = ptr.back(); - ptr.pop_back(); - basic_json& parent = result[ptr]; - - switch (parent.m_type) - { - case value_t::null: - case value_t::object: - { - // use operator[] to add value - parent[last_path] = val; - break; - } - - case value_t::array: - { - if (last_path == "-") - { - // special case: append to back - parent.push_back(val); - } - else - { - const auto idx = json_pointer::array_index(last_path); - if (JSON_HEDLEY_UNLIKELY(idx > parent.size())) - { - // avoid undefined behavior - JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range")); - } - - // default case: insert add offset - parent.insert(parent.begin() + static_cast(idx), val); - } - break; - } - - // if there exists a parent it cannot be primitive - default: // LCOV_EXCL_LINE - JSON_ASSERT(false); // LCOV_EXCL_LINE - } - }; - - // wrapper for "remove" operation; remove value at ptr - const auto operation_remove = [&result](json_pointer & ptr) - { - // get reference to parent of JSON pointer ptr - const auto last_path = ptr.back(); - ptr.pop_back(); - basic_json& parent = result.at(ptr); - - // remove child - if (parent.is_object()) - { - // perform range check - auto it = parent.find(last_path); - if (JSON_HEDLEY_LIKELY(it != parent.end())) - { - parent.erase(it); - } - else - { - JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found")); - } - } - else if (parent.is_array()) - { - // note erase performs range check - parent.erase(json_pointer::array_index(last_path)); - } - }; - - // type check: top level value must be an array - if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array())) - { - JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects")); - } - - // iterate and apply the operations - for (const auto& val : json_patch) - { - // wrapper to get a value for an operation - const auto get_value = [&val](const std::string & op, - const std::string & member, - bool string_type) -> basic_json & - { - // find value - auto it = val.m_value.object->find(member); - - // context-sensitive error message - const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'"; - - // check if desired value is present - if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end())) - { - JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'")); - } - - // check if result is of type string - if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string())) - { - JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'")); - } - - // no error: return value - return it->second; - }; - - // type check: every element of the array must be an object - if (JSON_HEDLEY_UNLIKELY(!val.is_object())) - { - JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects")); - } - - // collect mandatory members - const auto op = get_value("op", "op", true).template get(); - const auto path = get_value(op, "path", true).template get(); - json_pointer ptr(path); - - switch (get_op(op)) - { - case patch_operations::add: - { - operation_add(ptr, get_value("add", "value", false)); - break; - } - - case patch_operations::remove: - { - operation_remove(ptr); - break; - } - - case patch_operations::replace: - { - // the "path" location must exist - use at() - result.at(ptr) = get_value("replace", "value", false); - break; - } - - case patch_operations::move: - { - const auto from_path = get_value("move", "from", true).template get(); - json_pointer from_ptr(from_path); - - // the "from" location must exist - use at() - basic_json v = result.at(from_ptr); - - // The move operation is functionally identical to a - // "remove" operation on the "from" location, followed - // immediately by an "add" operation at the target - // location with the value that was just removed. - operation_remove(from_ptr); - operation_add(ptr, v); - break; - } - - case patch_operations::copy: - { - const auto from_path = get_value("copy", "from", true).template get(); - const json_pointer from_ptr(from_path); - - // the "from" location must exist - use at() - basic_json v = result.at(from_ptr); - - // The copy is functionally identical to an "add" - // operation at the target location using the value - // specified in the "from" member. - operation_add(ptr, v); - break; - } - - case patch_operations::test: - { - bool success = false; - JSON_TRY - { - // check if "value" matches the one at "path" - // the "path" location must exist - use at() - success = (result.at(ptr) == get_value("test", "value", false)); - } - JSON_INTERNAL_CATCH (out_of_range&) - { - // ignore out of range errors: success remains false - } - - // throw an exception if test fails - if (JSON_HEDLEY_UNLIKELY(!success)) - { - JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump())); - } - - break; - } - - default: - { - // op must be "add", "remove", "replace", "move", "copy", or - // "test" - JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid")); - } - } - } - - return result; - } - - /*! - @brief creates a diff as a JSON patch - - Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can - be changed into the value @a target by calling @ref patch function. - - @invariant For two JSON values @a source and @a target, the following code - yields always `true`: - @code {.cpp} - source.patch(diff(source, target)) == target; - @endcode - - @note Currently, only `remove`, `add`, and `replace` operations are - generated. - - @param[in] source JSON value to compare from - @param[in] target JSON value to compare against - @param[in] path helper value to create JSON pointers - - @return a JSON patch to convert the @a source to @a target - - @complexity Linear in the lengths of @a source and @a target. - - @liveexample{The following code shows how a JSON patch is created as a - diff for two JSON values.,diff} - - @sa @ref patch -- apply a JSON patch - @sa @ref merge_patch -- apply a JSON Merge Patch - - @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902) - - @since version 2.0.0 - */ - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json diff(const basic_json& source, const basic_json& target, - const std::string& path = "") - { - // the patch - basic_json result(value_t::array); - - // if the values are the same, return empty patch - if (source == target) - { - return result; - } - - if (source.type() != target.type()) - { - // different types: replace value - result.push_back( - { - {"op", "replace"}, {"path", path}, {"value", target} - }); - return result; - } - - switch (source.type()) - { - case value_t::array: - { - // first pass: traverse common elements - std::size_t i = 0; - while (i < source.size() && i < target.size()) - { - // recursive call to compare array values at index i - auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i)); - result.insert(result.end(), temp_diff.begin(), temp_diff.end()); - ++i; - } - - // i now reached the end of at least one array - // in a second pass, traverse the remaining elements - - // remove my remaining elements - const auto end_index = static_cast(result.size()); - while (i < source.size()) - { - // add operations in reverse order to avoid invalid - // indices - result.insert(result.begin() + end_index, object( - { - {"op", "remove"}, - {"path", path + "/" + std::to_string(i)} - })); - ++i; - } - - // add other remaining elements - while (i < target.size()) - { - result.push_back( - { - {"op", "add"}, - {"path", path + "/-"}, - {"value", target[i]} - }); - ++i; - } - - break; - } - - case value_t::object: - { - // first pass: traverse this object's elements - for (auto it = source.cbegin(); it != source.cend(); ++it) - { - // escape the key name to be used in a JSON patch - const auto key = json_pointer::escape(it.key()); - - if (target.find(it.key()) != target.end()) - { - // recursive call to compare object values at key it - auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key); - result.insert(result.end(), temp_diff.begin(), temp_diff.end()); - } - else - { - // found a key that is not in o -> remove it - result.push_back(object( - { - {"op", "remove"}, {"path", path + "/" + key} - })); - } - } - - // second pass: traverse other object's elements - for (auto it = target.cbegin(); it != target.cend(); ++it) - { - if (source.find(it.key()) == source.end()) - { - // found a key that is not in this -> add it - const auto key = json_pointer::escape(it.key()); - result.push_back( - { - {"op", "add"}, {"path", path + "/" + key}, - {"value", it.value()} - }); - } - } - - break; - } - - default: - { - // both primitive type: replace value - result.push_back( - { - {"op", "replace"}, {"path", path}, {"value", target} - }); - break; - } - } - - return result; - } - - /// @} - - //////////////////////////////// - // JSON Merge Patch functions // - //////////////////////////////// - - /// @name JSON Merge Patch functions - /// @{ - - /*! - @brief applies a JSON Merge Patch - - The merge patch format is primarily intended for use with the HTTP PATCH - method as a means of describing a set of modifications to a target - resource's content. This function applies a merge patch to the current - JSON value. - - The function implements the following algorithm from Section 2 of - [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396): - - ``` - define MergePatch(Target, Patch): - if Patch is an Object: - if Target is not an Object: - Target = {} // Ignore the contents and set it to an empty Object - for each Name/Value pair in Patch: - if Value is null: - if Name exists in Target: - remove the Name/Value pair from Target - else: - Target[Name] = MergePatch(Target[Name], Value) - return Target - else: - return Patch - ``` - - Thereby, `Target` is the current object; that is, the patch is applied to - the current value. - - @param[in] apply_patch the patch to apply - - @complexity Linear in the lengths of @a patch. - - @liveexample{The following code shows how a JSON Merge Patch is applied to - a JSON document.,merge_patch} - - @sa @ref patch -- apply a JSON patch - @sa [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396) - - @since version 3.0.0 - */ - void merge_patch(const basic_json& apply_patch) - { - if (apply_patch.is_object()) - { - if (!is_object()) - { - *this = object(); - } - for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it) - { - if (it.value().is_null()) - { - erase(it.key()); - } - else - { - operator[](it.key()).merge_patch(it.value()); - } - } - } - else - { - *this = apply_patch; - } - } - - /// @} -}; - -/*! -@brief user-defined to_string function for JSON values - -This function implements a user-defined to_string for JSON objects. - -@param[in] j a JSON object -@return a std::string object -*/ - -NLOHMANN_BASIC_JSON_TPL_DECLARATION -std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j) -{ - return j.dump(); -} -} // namespace nlohmann - -/////////////////////// -// nonmember support // -/////////////////////// - -// specialization of std::swap, and std::hash -namespace std -{ - -/// hash value for JSON objects -template<> -struct hash -{ - /*! - @brief return a hash value for a JSON object - - @since version 1.0.0 - */ - std::size_t operator()(const nlohmann::json& j) const - { - return nlohmann::detail::hash(j); - } -}; - -/// specialization for std::less -/// @note: do not remove the space after '<', -/// see https://github.com/nlohmann/json/pull/679 -template<> -struct less<::nlohmann::detail::value_t> -{ - /*! - @brief compare two value_t enum values - @since version 3.0.0 - */ - bool operator()(nlohmann::detail::value_t lhs, - nlohmann::detail::value_t rhs) const noexcept - { - return nlohmann::detail::operator<(lhs, rhs); - } -}; - -// C++20 prohibit function specialization in the std namespace. -#ifndef JSON_HAS_CPP_20 - -/*! -@brief exchanges the values of two JSON objects - -@since version 1.0.0 -*/ -template<> -inline void swap(nlohmann::json& j1, nlohmann::json& j2) noexcept( - is_nothrow_move_constructible::value&& - is_nothrow_move_assignable::value - ) -{ - j1.swap(j2); -} - -#endif - -} // namespace std - -/*! -@brief user-defined string literal for JSON values - -This operator implements a user-defined string literal for JSON objects. It -can be used by adding `"_json"` to a string literal and returns a JSON object -if no parse error occurred. - -@param[in] s a string representation of a JSON object -@param[in] n the length of string @a s -@return a JSON object - -@since version 1.0.0 -*/ -JSON_HEDLEY_NON_NULL(1) -inline nlohmann::json operator "" _json(const char* s, std::size_t n) -{ - return nlohmann::json::parse(s, s + n); -} - -/*! -@brief user-defined string literal for JSON pointer - -This operator implements a user-defined string literal for JSON Pointers. It -can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer -object if no parse error occurred. - -@param[in] s a string representation of a JSON Pointer -@param[in] n the length of string @a s -@return a JSON pointer object - -@since version 2.0.0 -*/ -JSON_HEDLEY_NON_NULL(1) -inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n) -{ - return nlohmann::json::json_pointer(std::string(s, n)); -} - -// #include - - -// restore GCC/clang diagnostic settings -#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) - #pragma GCC diagnostic pop -#endif -#if defined(__clang__) - #pragma GCC diagnostic pop -#endif - -// clean up -#undef JSON_ASSERT -#undef JSON_INTERNAL_CATCH -#undef JSON_CATCH -#undef JSON_THROW -#undef JSON_TRY -#undef JSON_HAS_CPP_14 -#undef JSON_HAS_CPP_17 -#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION -#undef NLOHMANN_BASIC_JSON_TPL -#undef JSON_EXPLICIT - -// #include -#undef JSON_HEDLEY_ALWAYS_INLINE -#undef JSON_HEDLEY_ARM_VERSION -#undef JSON_HEDLEY_ARM_VERSION_CHECK -#undef JSON_HEDLEY_ARRAY_PARAM -#undef JSON_HEDLEY_ASSUME -#undef JSON_HEDLEY_BEGIN_C_DECLS -#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE -#undef JSON_HEDLEY_CLANG_HAS_BUILTIN -#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE -#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE -#undef JSON_HEDLEY_CLANG_HAS_EXTENSION -#undef JSON_HEDLEY_CLANG_HAS_FEATURE -#undef JSON_HEDLEY_CLANG_HAS_WARNING -#undef JSON_HEDLEY_COMPCERT_VERSION -#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK -#undef JSON_HEDLEY_CONCAT -#undef JSON_HEDLEY_CONCAT3 -#undef JSON_HEDLEY_CONCAT3_EX -#undef JSON_HEDLEY_CONCAT_EX -#undef JSON_HEDLEY_CONST -#undef JSON_HEDLEY_CONSTEXPR -#undef JSON_HEDLEY_CONST_CAST -#undef JSON_HEDLEY_CPP_CAST -#undef JSON_HEDLEY_CRAY_VERSION -#undef JSON_HEDLEY_CRAY_VERSION_CHECK -#undef JSON_HEDLEY_C_DECL -#undef JSON_HEDLEY_DEPRECATED -#undef JSON_HEDLEY_DEPRECATED_FOR -#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL -#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ -#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED -#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES -#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS -#undef JSON_HEDLEY_DIAGNOSTIC_POP -#undef JSON_HEDLEY_DIAGNOSTIC_PUSH -#undef JSON_HEDLEY_DMC_VERSION -#undef JSON_HEDLEY_DMC_VERSION_CHECK -#undef JSON_HEDLEY_EMPTY_BASES -#undef JSON_HEDLEY_EMSCRIPTEN_VERSION -#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK -#undef JSON_HEDLEY_END_C_DECLS -#undef JSON_HEDLEY_FLAGS -#undef JSON_HEDLEY_FLAGS_CAST -#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE -#undef JSON_HEDLEY_GCC_HAS_BUILTIN -#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE -#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE -#undef JSON_HEDLEY_GCC_HAS_EXTENSION -#undef JSON_HEDLEY_GCC_HAS_FEATURE -#undef JSON_HEDLEY_GCC_HAS_WARNING -#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK -#undef JSON_HEDLEY_GCC_VERSION -#undef JSON_HEDLEY_GCC_VERSION_CHECK -#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE -#undef JSON_HEDLEY_GNUC_HAS_BUILTIN -#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE -#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE -#undef JSON_HEDLEY_GNUC_HAS_EXTENSION -#undef JSON_HEDLEY_GNUC_HAS_FEATURE -#undef JSON_HEDLEY_GNUC_HAS_WARNING -#undef JSON_HEDLEY_GNUC_VERSION -#undef JSON_HEDLEY_GNUC_VERSION_CHECK -#undef JSON_HEDLEY_HAS_ATTRIBUTE -#undef JSON_HEDLEY_HAS_BUILTIN -#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE -#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS -#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE -#undef JSON_HEDLEY_HAS_EXTENSION -#undef JSON_HEDLEY_HAS_FEATURE -#undef JSON_HEDLEY_HAS_WARNING -#undef JSON_HEDLEY_IAR_VERSION -#undef JSON_HEDLEY_IAR_VERSION_CHECK -#undef JSON_HEDLEY_IBM_VERSION -#undef JSON_HEDLEY_IBM_VERSION_CHECK -#undef JSON_HEDLEY_IMPORT -#undef JSON_HEDLEY_INLINE -#undef JSON_HEDLEY_INTEL_VERSION -#undef JSON_HEDLEY_INTEL_VERSION_CHECK -#undef JSON_HEDLEY_IS_CONSTANT -#undef JSON_HEDLEY_IS_CONSTEXPR_ -#undef JSON_HEDLEY_LIKELY -#undef JSON_HEDLEY_MALLOC -#undef JSON_HEDLEY_MESSAGE -#undef JSON_HEDLEY_MSVC_VERSION -#undef JSON_HEDLEY_MSVC_VERSION_CHECK -#undef JSON_HEDLEY_NEVER_INLINE -#undef JSON_HEDLEY_NON_NULL -#undef JSON_HEDLEY_NO_ESCAPE -#undef JSON_HEDLEY_NO_RETURN -#undef JSON_HEDLEY_NO_THROW -#undef JSON_HEDLEY_NULL -#undef JSON_HEDLEY_PELLES_VERSION -#undef JSON_HEDLEY_PELLES_VERSION_CHECK -#undef JSON_HEDLEY_PGI_VERSION -#undef JSON_HEDLEY_PGI_VERSION_CHECK -#undef JSON_HEDLEY_PREDICT -#undef JSON_HEDLEY_PRINTF_FORMAT -#undef JSON_HEDLEY_PRIVATE -#undef JSON_HEDLEY_PUBLIC -#undef JSON_HEDLEY_PURE -#undef JSON_HEDLEY_REINTERPRET_CAST -#undef JSON_HEDLEY_REQUIRE -#undef JSON_HEDLEY_REQUIRE_CONSTEXPR -#undef JSON_HEDLEY_REQUIRE_MSG -#undef JSON_HEDLEY_RESTRICT -#undef JSON_HEDLEY_RETURNS_NON_NULL -#undef JSON_HEDLEY_SENTINEL -#undef JSON_HEDLEY_STATIC_ASSERT -#undef JSON_HEDLEY_STATIC_CAST -#undef JSON_HEDLEY_STRINGIFY -#undef JSON_HEDLEY_STRINGIFY_EX -#undef JSON_HEDLEY_SUNPRO_VERSION -#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK -#undef JSON_HEDLEY_TINYC_VERSION -#undef JSON_HEDLEY_TINYC_VERSION_CHECK -#undef JSON_HEDLEY_TI_ARMCL_VERSION -#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK -#undef JSON_HEDLEY_TI_CL2000_VERSION -#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK -#undef JSON_HEDLEY_TI_CL430_VERSION -#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK -#undef JSON_HEDLEY_TI_CL6X_VERSION -#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK -#undef JSON_HEDLEY_TI_CL7X_VERSION -#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK -#undef JSON_HEDLEY_TI_CLPRU_VERSION -#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK -#undef JSON_HEDLEY_TI_VERSION -#undef JSON_HEDLEY_TI_VERSION_CHECK -#undef JSON_HEDLEY_UNAVAILABLE -#undef JSON_HEDLEY_UNLIKELY -#undef JSON_HEDLEY_UNPREDICTABLE -#undef JSON_HEDLEY_UNREACHABLE -#undef JSON_HEDLEY_UNREACHABLE_RETURN -#undef JSON_HEDLEY_VERSION -#undef JSON_HEDLEY_VERSION_DECODE_MAJOR -#undef JSON_HEDLEY_VERSION_DECODE_MINOR -#undef JSON_HEDLEY_VERSION_DECODE_REVISION -#undef JSON_HEDLEY_VERSION_ENCODE -#undef JSON_HEDLEY_WARNING -#undef JSON_HEDLEY_WARN_UNUSED_RESULT -#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG -#undef JSON_HEDLEY_FALL_THROUGH - - - -#endif // INCLUDE_NLOHMANN_JSON_HPP_ diff --git a/include/openspace/camera/camera.h b/include/openspace/camera/camera.h index 99fcba95fd..298391f336 100644 --- a/include/openspace/camera/camera.h +++ b/include/openspace/camera/camera.h @@ -137,11 +137,8 @@ public: } sgctInternal; // @TODO use Camera::SgctInternal interface instead - // [[deprecated("Replaced by Camera::SgctInternal::viewMatrix()")]] const glm::mat4& viewMatrix() const; - // [[deprecated("Replaced by Camera::SgctInternal::projectionMatrix()")]] const glm::mat4& projectionMatrix() const; - // [[deprecated("Replaced by Camera::SgctInternal::viewProjectionMatrix()")]] const glm::mat4& viewProjectionMatrix() const; std::vector syncables(); diff --git a/include/openspace/documentation/documentationengine.h b/include/openspace/documentation/documentationengine.h index 8cc76bf509..4b8c08e1bc 100644 --- a/include/openspace/documentation/documentationengine.h +++ b/include/openspace/documentation/documentationengine.h @@ -39,23 +39,6 @@ namespace openspace::documentation { */ class DocumentationEngine { public: - /** - * This exception is thrown by the addDocumentation method if a provided Documentation - * has an identifier, but the identifier was registered previously. - */ - struct DuplicateDocumentationException : public ghoul::RuntimeError { - /** - * Constructor of a DuplicateDocumentationException storing the offending - * Documentation for later use. - * - * \param doc The Documentation whose identifier was previously registered - */ - explicit DuplicateDocumentationException(Documentation doc); - - /// The offending Documentation whose identifier was previously registered - Documentation documentation; - }; - DocumentationEngine(); /** diff --git a/include/openspace/documentation/verifier.h b/include/openspace/documentation/verifier.h index 70d69a5c7a..7a02a2cf06 100644 --- a/include/openspace/documentation/verifier.h +++ b/include/openspace/documentation/verifier.h @@ -27,8 +27,6 @@ #include #include -#include -#include #include namespace openspace::documentation { @@ -193,30 +191,40 @@ public: /** * A Verifier that checks whether a given key inside a ghoul::Dictionary is a string and - * refers to an existing file on disk. + * optionally refers to an existing file on disk. */ class FileVerifier : public StringVerifier { public: - FileVerifier(); + explicit FileVerifier(bool fileMustExist = true); TestResult operator()(const ghoul::Dictionary& dict, const std::string& key) const override; std::string type() const override; + + bool mustExist() const; + +private: + bool _fileMustExist = true; }; /** * A Verifier that checks whether a given key inside a ghoul::Dictionary is a string and - * refers to an existing directory on disk. + * optionally refers to an existing directory on disk. */ class DirectoryVerifier : public StringVerifier { public: - DirectoryVerifier(); + explicit DirectoryVerifier(bool directoryMustExist = true); TestResult operator()(const ghoul::Dictionary& dict, const std::string& key) const override; std::string type() const override; + + bool mustExist() const; + +private: + bool _directoryMustExist = true; }; /** diff --git a/include/openspace/documentation/verifier.inl b/include/openspace/documentation/verifier.inl index 7ba00334f6..61aa451861 100644 --- a/include/openspace/documentation/verifier.inl +++ b/include/openspace/documentation/verifier.inl @@ -22,13 +22,11 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include - -#include #include +#include +#include #include #include -#include namespace openspace::documentation { @@ -682,7 +680,6 @@ std::string NotInRangeVerifier::documentation() const { ghoul::to_string(upper) + " )"; } - template AnnotationVerifier::AnnotationVerifier(std::string a) : annotation(std::move(a)) diff --git a/include/openspace/engine/configuration.h b/include/openspace/engine/configuration.h index 609caafe16..920b6b51b6 100644 --- a/include/openspace/engine/configuration.h +++ b/include/openspace/engine/configuration.h @@ -25,6 +25,7 @@ #ifndef __OPENSPACE_CORE___CONFIGURATION___H__ #define __OPENSPACE_CORE___CONFIGURATION___H__ +#include #include #include #include @@ -54,6 +55,8 @@ struct Configuration { properties::Property::Visibility propertyVisibility = properties::Property::Visibility::User; + bool showPropertyConfirmation = true; + std::vector globalCustomizationScripts; std::map pathTokens = { { "CACHE" , "CACHE = \"${BASE}/cache\"" } diff --git a/include/openspace/engine/globals.h b/include/openspace/engine/globals.h index 6eca1b720e..c85039cf88 100644 --- a/include/openspace/engine/globals.h +++ b/include/openspace/engine/globals.h @@ -25,7 +25,6 @@ #ifndef __OPENSPACE_CORE___GLOBALS___H__ #define __OPENSPACE_CORE___GLOBALS___H__ -#include #include #include diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index edeb821dac..597d09f295 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -26,12 +26,12 @@ #define __OPENSPACE_CORE___OPENSPACEENGINE___H__ #include -#include +#include +#include #include #include #include #include -#include #include #include #include @@ -71,6 +71,8 @@ struct CommandlineArguments { std::optional profile; std::optional propertyVisibility; std::optional bypassLauncher; + + std::optional task; }; class OpenSpaceEngine : public properties::PropertyOwner { @@ -132,6 +134,11 @@ public: AssetManager& assetManager(); LoadingScreen* loadingScreen(); + void invalidatePropertyCache(); + void invalidatePropertyOwnerCache(); + const std::vector& allProperties() const; + const std::vector& allPropertyOwners() const; + void createUserDirectoriesIfNecessary(); uint64_t ramInUse() const; @@ -151,6 +158,7 @@ private: properties::BoolProperty _printEvents; properties::OptionProperty _visibility; + properties::BoolProperty _showPropertyConfirmationDialog; properties::FloatProperty _fadeOnEnableDuration; properties::BoolProperty _disableAllMouseInputs; @@ -174,6 +182,12 @@ private: int _nextCallbackHandle = 0; std::vector> _modeChangeCallbacks; + + mutable bool _isAllPropertiesCacheDirty = true; + mutable std::vector _allPropertiesCache; + + mutable bool _isAllPropertyOwnersCacheDirty = true; + mutable std::vector _allPropertyOwnersCache; }; /** diff --git a/include/openspace/engine/settings.h b/include/openspace/engine/settings.h index d167d8544d..f0c514ee8b 100644 --- a/include/openspace/engine/settings.h +++ b/include/openspace/engine/settings.h @@ -35,8 +35,12 @@ namespace openspace { struct Settings { auto operator<=>(const Settings&) const = default; + // Settings that are not configurable by the user and that represent a persistent + // state for the system std::optional hasStartedBefore; + std::optional lastStartedDate; + // Configurable settings std::optional configuration; std::optional rememberLastConfiguration; std::optional profile; diff --git a/include/openspace/engine/syncengine.h b/include/openspace/engine/syncengine.h index d4516bfb43..d26907f22e 100644 --- a/include/openspace/engine/syncengine.h +++ b/include/openspace/engine/syncengine.h @@ -37,7 +37,7 @@ class Syncable; /** * Manages a collection of `Syncable`s and ensures they are synchronized over SGCT nodes. - * Encoding/Decoding order is handles internally. + * Encoding/Decoding order is handled internally. */ class SyncEngine { public: diff --git a/include/openspace/engine/windowdelegate.h b/include/openspace/engine/windowdelegate.h index 73c6fa27fd..b71809cd4f 100644 --- a/include/openspace/engine/windowdelegate.h +++ b/include/openspace/engine/windowdelegate.h @@ -26,7 +26,6 @@ #define __OPENSPACE_CORE__WINDOWDELEGATE___H__ #include -#include #include namespace openspace { @@ -44,6 +43,7 @@ struct WindowDelegate { void (*setSynchronization)(bool enabled) = [](bool) {}; bool (*windowHasResized)() = []() { return false; }; + bool (*anyWindowHasResized)() = []() { return false; }; double (*averageDeltaTime)() = []() { return 0.0; }; @@ -100,9 +100,11 @@ struct WindowDelegate { int (*firstWindowId)() = []() { return 0; }; - double (*getHorizFieldOfView)() = []() { return 0.0; }; + std::string (*nameForWindow)(int windowIdx) = [](int) { return std::string(); }; - void (*setHorizFieldOfView)(float hFovDeg) = [](float) { }; + float (*horizFieldOfView)(int windowIdx) = [](int) { return 0.f; }; + + void (*setHorizFieldOfView)(int windowIdx, float hFovDeg) = [](int, float) {}; void* (*getNativeWindowHandle)(size_t windowIndex) = [](size_t) -> void* { return nullptr; @@ -129,6 +131,7 @@ struct WindowDelegate { [](const glm::vec2&) { return glm::vec2(0); }; void (*setStatisticsGraphScale)(float scale) = [](float) {}; + void (*setStatisticsGraphOffset)(glm::vec2 offset) = [](glm::vec2) {}; void (*setMouseCursor)(Cursor cursor) = [](Cursor) {}; }; diff --git a/include/openspace/events/event.h b/include/openspace/events/event.h index c43f4978ed..563e4c5a44 100644 --- a/include/openspace/events/event.h +++ b/include/openspace/events/event.h @@ -64,6 +64,8 @@ struct Event { ApplicationShutdown, CameraFocusTransition, TimeOfInterestReached, + MissionAdded, + MissionRemoved, MissionEventReached, PlanetEclipsed, InterpolationFinished, @@ -256,6 +258,38 @@ struct EventTimeOfInterestReached : public Event { }; +/** + * This event is created when a mission is added. + */ +struct EventMissionAdded : public Event { + static constexpr Type Type = Event::Type::MissionAdded; + + /** + * Creates an instance of an EventMissionAdded event. + * + * \param identifier The identifier of the mission added + */ + EventMissionAdded(std::string_view identifier); + + const tstring identifier; +}; + +/** + * This event is created when a mission is removed. + */ +struct EventMissionRemoved : public Event { + static constexpr Type Type = Event::Type::MissionRemoved; + + /** + * Creates an instance of an EventMissionRemoved event. + * + * \param identifier The identifier of the mission removed + */ + EventMissionRemoved(std::string_view identifier); + + const tstring identifier; +}; + /** * This event is created when the end of a mission phase is reached. This event is * currently unused. @@ -263,7 +297,7 @@ struct EventTimeOfInterestReached : public Event { struct EventMissionEventReached : public Event { static constexpr Type Type = Event::Type::MissionEventReached; - // Not sure which kind of parameters we want to pass here + // Not sure which kind of parameters we want to pass here. EventMissionEventReached(); }; @@ -276,7 +310,7 @@ struct EventPlanetEclipsed : public Event { /** * Creates an instance of an EventPlanetEclipsed event. - * + * \param eclipsee_ The scene graph node that is eclipsed by another object * \param eclipser_ The scene graph node that is eclipsing the other object * diff --git a/include/openspace/interaction/camerainteractionstates.h b/include/openspace/interaction/camerainteractionstates.h index 3f22a5eaf8..edd300a4dc 100644 --- a/include/openspace/interaction/camerainteractionstates.h +++ b/include/openspace/interaction/camerainteractionstates.h @@ -48,9 +48,9 @@ public: glm::dvec2 globalRotationVelocity() const; glm::dvec2 localRotationVelocity() const; - glm::dvec2 truckMovementVelocity() const; - glm::dvec2 localRollVelocity() const; - glm::dvec2 globalRollVelocity() const; + double truckMovementVelocity() const; + double localRollVelocity() const; + double globalRollVelocity() const; void resetVelocities(); @@ -61,22 +61,23 @@ public: bool hasNonZeroVelocities(bool checkOnlyMovement = false) const; protected: + template struct InteractionState { InteractionState(double scaleFactor); void setFriction(double friction); void setVelocityScaleFactor(double scaleFactor); - glm::dvec2 previousPosition = glm::dvec2(0.0); - DelayedVariable velocity; + T previousValue = T(0.0); + DelayedVariable velocity; }; double _sensitivity = 0.0; - InteractionState _globalRotationState; - InteractionState _localRotationState; - InteractionState _truckMovementState; - InteractionState _localRollState; - InteractionState _globalRollState; + InteractionState _globalRotationState; + InteractionState _localRotationState; + InteractionState _truckMovementState; + InteractionState _localRollState; + InteractionState _globalRollState; }; } // namespace openspace::interaction diff --git a/include/openspace/interaction/scriptcamerastates.h b/include/openspace/interaction/scriptcamerastates.h index 2aebcc070f..f9617f5cc3 100644 --- a/include/openspace/interaction/scriptcamerastates.h +++ b/include/openspace/interaction/scriptcamerastates.h @@ -37,16 +37,16 @@ public: void addLocalRotation(const glm::dvec2& delta); void addGlobalRotation(const glm::dvec2& delta); - void addTruckMovement(const glm::dvec2& delta); - void addLocalRoll(const glm::dvec2& delta); - void addGlobalRoll(const glm::dvec2& delta); + void addTruckMovement(double delta); + void addLocalRoll(double delta); + void addGlobalRoll(double delta); private: glm::dvec2 _localRotation = glm::dvec2(0.0); glm::dvec2 _globalRotation = glm::dvec2(0.0); - glm::dvec2 _truckMovement = glm::dvec2(0.0); - glm::dvec2 _localRoll = glm::dvec2(0.0); - glm::dvec2 _globalRoll = glm::dvec2(0.0); + double _truckMovement = 0.0; + double _localRoll = 0.0; + double _globalRoll = 0.0; }; } // namespace openspace::interaction diff --git a/include/openspace/interaction/sessionrecordinghandler.h b/include/openspace/interaction/sessionrecordinghandler.h index 3a92fe3c63..a3cc99fba9 100644 --- a/include/openspace/interaction/sessionrecordinghandler.h +++ b/include/openspace/interaction/sessionrecordinghandler.h @@ -106,7 +106,8 @@ public: * and all keyframes deleted from memory. * \param filename File saved with recorded keyframes */ - void stopRecording(const std::filesystem::path& filename, DataMode dataMode, bool overwrite = false); + void stopRecording(const std::filesystem::path& filename, DataMode dataMode, + bool overwrite = false); /** * Used to check if a session recording is in progress. diff --git a/include/openspace/json.h b/include/openspace/json.h index 0ee0f7f992..40df78b9c9 100644 --- a/include/openspace/json.h +++ b/include/openspace/json.h @@ -36,7 +36,12 @@ #pragma GCC diagnostic ignored "-Wuseless-cast" #endif // __GNUC__ -#include +#define JSON_HAS_CPP_11 +#define JSON_HAS_CPP_14 +#define JSON_HAS_CPP_17 +#define JSON_HAS_CPP_20 +#define JSON_USE_IMPLICIT_CONVERSIONS 0 +#include #if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic pop diff --git a/include/openspace/mission/missionmanager.h b/include/openspace/mission/missionmanager.h index b07dcd5973..50bd573e47 100644 --- a/include/openspace/mission/missionmanager.h +++ b/include/openspace/mission/missionmanager.h @@ -41,10 +41,6 @@ namespace scripting { struct LuaLibrary; } */ class MissionManager { public: - struct MissionManagerException : public ghoul::RuntimeError { - explicit MissionManagerException(std::string error); - }; - MissionManager(); /** diff --git a/include/openspace/navigation/navigationhandler.h b/include/openspace/navigation/navigationhandler.h index d9e37bcae9..3c0a01fc22 100644 --- a/include/openspace/navigation/navigationhandler.h +++ b/include/openspace/navigation/navigationhandler.h @@ -25,7 +25,8 @@ #ifndef __OPENSPACE_CORE___NAVIGATIONHANDLER___H__ #define __OPENSPACE_CORE___NAVIGATIONHANDLER___H__ -#include +#include + #include #include #include @@ -34,13 +35,10 @@ #include #include #include -#include -#include #include -#include +#include #include #include -#include namespace openspace { class Camera; @@ -52,12 +50,12 @@ namespace openspace::scripting { struct LuaLibrary; } namespace openspace::interaction { struct JoystickInputStates; -struct NavigationState; -struct NodeCameraStateSpec; -struct WebsocketInputStates; class KeyframeNavigator; +struct NavigationState; class OrbitalNavigator; class PathNavigator; +struct NodeCameraStateSpec; +struct WebsocketInputStates; class NavigationHandler : public properties::PropertyOwner { public: @@ -176,7 +174,7 @@ public: * \param fadeDuration An optional duration for the fading. If unspecified, use the * JumpToFadeDuration property */ - void triggerFadeToTransition(const std::string& transitionScript, + void triggerFadeToTransition(std::string transitionScript, std::optional fadeDuration = std::nullopt); /** diff --git a/include/openspace/navigation/orbitalnavigator.h b/include/openspace/navigation/orbitalnavigator.h index c75c51caa0..f3601b7bc3 100644 --- a/include/openspace/navigation/orbitalnavigator.h +++ b/include/openspace/navigation/orbitalnavigator.h @@ -33,11 +33,11 @@ #include #include #include -#include -#include +#include +#include +#include #include #include -#include #include #include #include @@ -181,7 +181,7 @@ private: void updatePreviousAnchorState(); void updatePreviousAimState(); - Camera* _camera; + Camera* _camera = nullptr; Friction _friction; diff --git a/include/openspace/navigation/pathnavigator.h b/include/openspace/navigation/pathnavigator.h index 97e95f1053..1cc0633d19 100644 --- a/include/openspace/navigation/pathnavigator.h +++ b/include/openspace/navigation/pathnavigator.h @@ -29,7 +29,7 @@ #include #include -#include +#include #include #include #include diff --git a/include/openspace/network/parallelpeer.h b/include/openspace/network/parallelpeer.h index 6882550974..a5cbbeab39 100644 --- a/include/openspace/network/parallelpeer.h +++ b/include/openspace/network/parallelpeer.h @@ -29,8 +29,8 @@ #include #include +#include #include -#include #include #include #include diff --git a/include/openspace/properties/list/doublelistproperty.h b/include/openspace/properties/list/doublelistproperty.h index 5cdbe76628..060c2a2142 100644 --- a/include/openspace/properties/list/doublelistproperty.h +++ b/include/openspace/properties/list/doublelistproperty.h @@ -25,7 +25,7 @@ #ifndef __OPENSPACE_CORE___DOUBLELISTPROPERTY___H__ #define __OPENSPACE_CORE___DOUBLELISTPROPERTY___H__ -#include +#include namespace openspace::properties { @@ -34,14 +34,17 @@ public: DoubleListProperty(Property::PropertyInfo info, std::vector values = std::vector()); - std::string_view className() const override; - ghoul::lua::LuaTypes typeLua() const override; + std::string_view className() const override final; + ghoul::lua::LuaTypes typeLua() const override final; + void getLuaValue(lua_State* state) const override final; + + std::string stringValue() const override final; using TemplateProperty>::operator std::vector; using TemplateProperty>::operator=; -protected: - std::string toStringConversion() const override; +private: + std::vector toValue(lua_State* state) const override final; }; } // namespace openspace::properties diff --git a/include/openspace/properties/list/intlistproperty.h b/include/openspace/properties/list/intlistproperty.h index 7dbde9f2e9..eb13bceba8 100644 --- a/include/openspace/properties/list/intlistproperty.h +++ b/include/openspace/properties/list/intlistproperty.h @@ -25,7 +25,7 @@ #ifndef __OPENSPACE_CORE___INTLISTPROPERTY___H__ #define __OPENSPACE_CORE___INTLISTPROPERTY___H__ -#include +#include namespace openspace::properties { @@ -34,14 +34,17 @@ public: IntListProperty(Property::PropertyInfo info, std::vector values = std::vector()); - std::string_view className() const override; - ghoul::lua::LuaTypes typeLua() const override; + std::string_view className() const override final; + ghoul::lua::LuaTypes typeLua() const override final; + void getLuaValue(lua_State* state) const override final; + + std::string stringValue() const override final; using TemplateProperty>::operator std::vector; using TemplateProperty>::operator=; -protected: - std::string toStringConversion() const override; +private: + std::vector toValue(lua_State* state) const override final; }; } // namespace openspace::properties diff --git a/include/openspace/properties/list/stringlistproperty.h b/include/openspace/properties/list/stringlistproperty.h index f6c21cfdce..ca56b50aea 100644 --- a/include/openspace/properties/list/stringlistproperty.h +++ b/include/openspace/properties/list/stringlistproperty.h @@ -25,7 +25,7 @@ #ifndef __OPENSPACE_CORE___STRINGLISTPROPERTY___H__ #define __OPENSPACE_CORE___STRINGLISTPROPERTY___H__ -#include +#include #include namespace openspace::properties { @@ -35,14 +35,17 @@ public: StringListProperty(Property::PropertyInfo info, std::vector values = std::vector()); - std::string_view className() const override; - ghoul::lua::LuaTypes typeLua() const override; + std::string_view className() const override final; + ghoul::lua::LuaTypes typeLua() const override final; + void getLuaValue(lua_State* state) const override final; + + std::string stringValue() const override final; using TemplateProperty>::operator std::vector; using TemplateProperty>::operator=; -protected: - std::string toStringConversion() const override; +private: + std::vector< std::string> toValue(lua_State* state) const override final; }; } // namespace openspace::properties diff --git a/include/openspace/properties/matrix/dmat2property.h b/include/openspace/properties/matrix/dmat2property.h index 89854b8f35..8c25086ef4 100644 --- a/include/openspace/properties/matrix/dmat2property.h +++ b/include/openspace/properties/matrix/dmat2property.h @@ -41,10 +41,16 @@ public: ghoul::createFillMat2x2(std::numeric_limits::max()), glm::dmat2x2 stepValue = ghoul::createFillMat2x2(0.01)); - std::string_view className() const override; - ghoul::lua::LuaTypes typeLua() const override; + std::string_view className() const override final; + ghoul::lua::LuaTypes typeLua() const override final; + void getLuaValue(lua_State* state) const override final; + + std::string stringValue() const override final; using TemplateProperty::operator=; + +private: + glm::dmat2x2 toValue(lua_State* state) const override final; }; } // namespace openspace::properties diff --git a/include/openspace/properties/matrix/dmat3property.h b/include/openspace/properties/matrix/dmat3property.h index 5de7441cdb..954e56e12a 100644 --- a/include/openspace/properties/matrix/dmat3property.h +++ b/include/openspace/properties/matrix/dmat3property.h @@ -41,10 +41,16 @@ public: ghoul::createFillMat3x3(std::numeric_limits::max()), glm::dmat3x3 stepValue = ghoul::createFillMat3x3(0.01)); - std::string_view className() const override; - ghoul::lua::LuaTypes typeLua() const override; + std::string_view className() const override final; + ghoul::lua::LuaTypes typeLua() const override final; + void getLuaValue(lua_State* state) const override final; + + std::string stringValue() const override final; using TemplateProperty::operator=; + +private: + glm::dmat3x3 toValue(lua_State* state) const override final; }; } // namespace openspace::properties diff --git a/include/openspace/properties/matrix/dmat4property.h b/include/openspace/properties/matrix/dmat4property.h index 4f43fd5745..3a21e502c9 100644 --- a/include/openspace/properties/matrix/dmat4property.h +++ b/include/openspace/properties/matrix/dmat4property.h @@ -41,10 +41,16 @@ public: ghoul::createFillMat4x4(std::numeric_limits::max()), glm::dmat4x4 stepValue = ghoul::createFillMat4x4(0.01)); - std::string_view className() const override; - ghoul::lua::LuaTypes typeLua() const override; + std::string_view className() const override final; + ghoul::lua::LuaTypes typeLua() const override final; + void getLuaValue(lua_State* state) const override final; + + std::string stringValue() const override final; using TemplateProperty::operator=; + +private: + glm::dmat4x4 toValue(lua_State* state) const override final; }; } // namespace openspace::properties diff --git a/include/openspace/properties/matrix/mat2property.h b/include/openspace/properties/matrix/mat2property.h index b818a9be2c..68513c377d 100644 --- a/include/openspace/properties/matrix/mat2property.h +++ b/include/openspace/properties/matrix/mat2property.h @@ -41,10 +41,16 @@ public: ghoul::createFillMat2x2(std::numeric_limits::max()), glm::mat2x2 stepValue = ghoul::createFillMat2x2(0.01f)); - std::string_view className() const override; - ghoul::lua::LuaTypes typeLua() const override; + std::string_view className() const override final; + ghoul::lua::LuaTypes typeLua() const override final; + void getLuaValue(lua_State* state) const override final; + + std::string stringValue() const override final; using TemplateProperty::operator=; + +private: + glm::mat2x2 toValue(lua_State* state) const override final; }; } // namespace openspace::properties diff --git a/include/openspace/properties/matrix/mat3property.h b/include/openspace/properties/matrix/mat3property.h index d857fbfe42..17cc04876e 100644 --- a/include/openspace/properties/matrix/mat3property.h +++ b/include/openspace/properties/matrix/mat3property.h @@ -41,10 +41,16 @@ public: ghoul::createFillMat3x3(std::numeric_limits::max()), glm::mat3x3 stepValue = ghoul::createFillMat3x3(0.01f)); - std::string_view className() const override; - ghoul::lua::LuaTypes typeLua() const override; + std::string_view className() const override final; + ghoul::lua::LuaTypes typeLua() const override final; + void getLuaValue(lua_State* state) const override final; + + std::string stringValue() const override final; using TemplateProperty::operator=; + +private: + glm::mat3x3 toValue(lua_State* state) const override final; }; } // namespace openspace::properties diff --git a/include/openspace/properties/matrix/mat4property.h b/include/openspace/properties/matrix/mat4property.h index 93d0eb83f4..790f48dc4c 100644 --- a/include/openspace/properties/matrix/mat4property.h +++ b/include/openspace/properties/matrix/mat4property.h @@ -41,10 +41,16 @@ public: ghoul::createFillMat4x4(std::numeric_limits::max()), glm::mat4x4 stepValue = ghoul::createFillMat4x4(0.01f)); - std::string_view className() const override; - ghoul::lua::LuaTypes typeLua() const override; + std::string_view className() const override final; + ghoul::lua::LuaTypes typeLua() const override final; + void getLuaValue(lua_State* state) const override final; + + std::string stringValue() const override final; using TemplateProperty::operator=; + +private: + glm::mat4x4 toValue(lua_State* state) const override final; }; } // namespace openspace::properties diff --git a/include/openspace/properties/listproperty.h b/include/openspace/properties/misc/listproperty.h similarity index 93% rename from include/openspace/properties/listproperty.h rename to include/openspace/properties/misc/listproperty.h index dc10f3fc25..aa70fb3d21 100644 --- a/include/openspace/properties/listproperty.h +++ b/include/openspace/properties/misc/listproperty.h @@ -36,14 +36,10 @@ public: ListProperty(Property::PropertyInfo info, std::vector values); virtual ~ListProperty() override = 0; - -protected: - std::vector fromLuaConversion(lua_State* state) const override; - void toLuaConversion(lua_State* state) const override; }; } // namespace openspace::properties -#include "openspace/properties/listproperty.inl" +#include "openspace/properties/misc/listproperty.inl" #endif // __OPENSPACE_CORE___LISTPROPERTY___H__ diff --git a/include/openspace/properties/listproperty.inl b/include/openspace/properties/misc/listproperty.inl similarity index 88% rename from include/openspace/properties/listproperty.inl rename to include/openspace/properties/misc/listproperty.inl index 6d17be9a39..5f26c193f2 100644 --- a/include/openspace/properties/listproperty.inl +++ b/include/openspace/properties/misc/listproperty.inl @@ -32,15 +32,5 @@ ListProperty::ListProperty(Property::PropertyInfo info, std::vector values template ListProperty::~ListProperty() {} -template -std::vector ListProperty::fromLuaConversion(lua_State* state) const { - return ghoul::lua::value>(state); -} - -template -void ListProperty::toLuaConversion(lua_State* state) const { - ghoul::lua::push(state, TemplateProperty>::_value); -} - } // namespace openspace::properties diff --git a/include/openspace/properties/optionproperty.h b/include/openspace/properties/misc/optionproperty.h similarity index 82% rename from include/openspace/properties/optionproperty.h rename to include/openspace/properties/misc/optionproperty.h index 8e09fb43a3..deeadd946d 100644 --- a/include/openspace/properties/optionproperty.h +++ b/include/openspace/properties/misc/optionproperty.h @@ -37,7 +37,7 @@ namespace openspace::properties { * options can be queried using the options method. Only values representing valid options * can be used to set this property, or an error will be logged. */ -class OptionProperty : public IntProperty { +class OptionProperty : public NumericalProperty { public: /** * The struct storing a single option consisting of an integer `value` and a `string` @@ -48,11 +48,6 @@ public: std::string description; }; - enum class DisplayType { - Radio, - Dropdown - }; - /** * The constructor delegating the `identifier` and the `guiName` to its super class. * @@ -64,43 +59,24 @@ public: */ OptionProperty(Property::PropertyInfo info); - /** - * The constructor delegating the `identifier` and the `guiName` to its super class. - * - * \param info The PropertyInfo structure that contains all the required static - * information for initializing this Property - * \param displayType Optional DisplayType for GUI (default RADIO) - * - * \pre \p info.identifier must not be empty - * \pre \p info.guiName must not be empty - */ - OptionProperty(PropertyInfo info, DisplayType displayType); - /** * Returns the name of the class for reflection purposes. * * \return The name of this class for reflection purposes */ - std::string_view className() const override; - ghoul::lua::LuaTypes typeLua() const override; + std::string_view className() const override final; + ghoul::lua::LuaTypes typeLua() const override final; - using IntProperty::operator=; - - /** - * Returns the type for GUI display. - * - * \return OptionType for display purposes - */ - DisplayType displayType() const; + using TemplateProperty::operator=; /** * Adds the passed option to the list of available options. The `value` of the * `option` must not have been registered previously, or a warning will be logged. * * \param value The option that will be added to the list of available options - * \param desc The description of the value that will be added + * \param description The description of the value that will be added */ - void addOption(int value, std::string desc); + void addOption(int value, std::string description); /** * Adds multiple options to the OptionProperty. Each value in the vector consists of @@ -160,14 +136,16 @@ public: */ std::string getDescriptionByValue(int value); + void getLuaValue(lua_State* state) const override final; + void setLuaValue(lua_State* state) override final; + std::string stringValue() const override final; + private: - static const std::string OptionsKey; - int fromLuaConversion(lua_State* state) const override; - std::string generateAdditionalJsonDescription() const override; + nlohmann::json generateAdditionalJsonDescription() const override final; + int toValue(lua_State* state) const override final; /// The list of options which have been registered with this OptionProperty std::vector